Subversion Repositories Scribus

Rev

Rev 8440 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4430 cbradney 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
3 paul 7
/***************************************************************************
8
                          mspinbox.cpp  -  description
9
                             -------------------
10
    begin                : Sat Jun 16 2001
11
    copyright            : (C) 2001 by Franz Schmid
12
    email                : Franz.Schmid@altmuehlnet.de
13
 ***************************************************************************/
14
 
15
/***************************************************************************
16
 *                                                                         *
17
 *   This program is free software; you can redistribute it and/or modify  *
18
 *   it under the terms of the GNU General Public License as published by  *
19
 *   the Free Software Foundation; either version 2 of the License, or     *
20
 *   (at your option) any later version.                                   *
21
 *                                                                         *
22
 ***************************************************************************/
23
 
24
#include "mspinbox.h"
280 Franz 25
#include "mspinbox.moc"
137 Franz 26
#include <qapplication.h>
333 Franz 27
#include <qlineedit.h>
4112 cbradney 28
#include <qregexp.h>
1568 cbradney 29
#include <cmath>
137 Franz 30
#include "fparser.h"
1568 cbradney 31
#include "units.h"
3 paul 32
 
146 Franz 33
 
3 paul 34
MSpinBox::MSpinBox(QWidget *pa, int s):QSpinBox(pa)
35
{
333 Franz 36
        setParameters(s);
37
        setValidator(0);
38
        ed = editor();
39
        QSpinBox::setLineStep(Decimals);
40
        oldLineStep=0;
41
        readOnly=false;
1617 fschmid 42
        edited = false;
43
    connect( ed, SIGNAL(textChanged(const QString&)), SLOT(textChanged()) );
333 Franz 44
}
45
 
46
MSpinBox::MSpinBox(double minValue, double maxValue, QWidget *pa, int s):QSpinBox(pa)
47
{
48
        setParameters(s);
49
        setValidator(0);
50
        ed = editor();
51
        QSpinBox::setLineStep(Decimals);
52
        oldLineStep=0;
53
        setMinValue(minValue);
54
        setMaxValue(maxValue);
55
        readOnly=false;
1617 fschmid 56
        edited = false;
57
    connect( ed, SIGNAL(textChanged(const QString&)), SLOT(textChanged()) );
333 Franz 58
}
59
 
60
void MSpinBox::setParameters( int s )
61
{
1795 cbradney 62
        if (s>=0 && s <=unitGetMaxIndex())
161 Franz 63
        {
1568 cbradney 64
                Width=s;
10812 cbradney 65
                Decimals=static_cast<int>(pow(10.0, s));
161 Franz 66
        }
1568 cbradney 67
        else
68
        {
69
                Width = 2;
70
                Decimals = 100;
71
        }
1617 fschmid 72
        edited = false;
3 paul 73
}
74
 
75
bool MSpinBox::eventFilter( QObject* ob, QEvent* ev )
76
{
2680 cbradney 77
        bool retval = false;
3 paul 78
        if ( ev->type() == QEvent::KeyPress )
161 Franz 79
        {
3 paul 80
                QKeyEvent* k = (QKeyEvent*)ev;
6004 cbradney 81
                bool shiftB=k->state() & ShiftButton;
82
                bool controlB=k->state() & ControlButton;
83
                if (k->key() == Key_Shift && !controlB)
161 Franz 84
                {
138 Franz 85
                        setLineStep(QMAX(Decimals / 10, 1));
3 paul 86
                        retval = true;
6004 cbradney 87
                        qApp->sendEvent( this, ev );
3 paul 88
                        return retval;
89
                }
6004 cbradney 90
                else if (k->key() == Key_Control && !shiftB)
3736 fschmid 91
                {
92
                        setLineStep(QMAX(Decimals * 10, 1));
93
                        retval = true;
6004 cbradney 94
                        qApp->sendEvent( this, ev );
3736 fschmid 95
                        return retval;
96
                }
6004 cbradney 97
                else if ((k->key() == Key_Control && shiftB) || (k->key() == Key_Shift && controlB))
98
                {
99
                        setLineStep(QMAX(Decimals / 100, 1));
100
                        retval = true;
101
                        qApp->sendEvent( this, ev );
102
                        return retval;
103
                }
161 Franz 104
        }
3736 fschmid 105
        if (ev->type() == QEvent::KeyRelease )
161 Franz 106
        {
3 paul 107
                QKeyEvent* k = (QKeyEvent*)ev;
6004 cbradney 108
                bool shiftB=k->stateAfter() & ShiftButton;
109
                bool controlB=k->stateAfter() & ControlButton;
110
                if ((k->key() == Key_Shift && !controlB) || (k->key() == Key_Control && !shiftB))
161 Franz 111
                {
3 paul 112
                        setLineStep(Decimals);
113
                        retval = true;
161 Franz 114
                    qApp->sendEvent( this, ev );
3 paul 115
                        return retval;
364 Franz 116
                }
6004 cbradney 117
                else if (k->key() == Key_Shift && controlB)
118
                {
119
                        setLineStep(QMAX(Decimals * 10, 1));
120
                        retval = true;
121
                        qApp->sendEvent( this, ev );
122
                        return retval;
123
                }
124
                else if (k->key() == Key_Control && shiftB)
125
                {
126
                        setLineStep(QMAX(Decimals / 10, 1));
127
                        retval = true;
128
                        qApp->sendEvent( this, ev );
129
                        return retval;
130
                }
364 Franz 131
        }
132
        if ( ev->type() == QEvent::Wheel )
133
        {
4013 cbradney 134
                //If read only dont spin
135
                if (readOnly)
136
                        return false;
364 Franz 137
                QWheelEvent* k = (QWheelEvent*)ev;
4027 cbradney 138
                bool shiftB=k->state() & ShiftButton;
139
                bool controlB=k->state() & ControlButton;
140
                if (shiftB && !controlB)
364 Franz 141
                {
142
                        setLineStep(QMAX(Decimals / 10, 1));
143
                        retval = true;
144
                        qApp->sendEvent( this, ev );
145
                        return retval;
6004 cbradney 146
                }
4027 cbradney 147
                else if (!shiftB && controlB)
364 Franz 148
                {
3736 fschmid 149
                        setLineStep(QMAX(Decimals * 10, 1));
150
                        retval = true;
151
                    qApp->sendEvent( this, ev );
152
                        return retval;
153
                }
4027 cbradney 154
                else if (shiftB && controlB)
3736 fschmid 155
                {
4027 cbradney 156
                        setLineStep(QMAX(Decimals / 100, 1));
157
                        retval = true;
158
                    qApp->sendEvent( this, ev );
159
                        return retval;
160
                }
161
                else
162
                if (!shiftB && !controlB)
163
                {
364 Franz 164
                        setLineStep(Decimals);
165
                        retval = true;
166
                        qApp->sendEvent( this, ev );
167
                        return retval;
4027 cbradney 168
                }
161 Franz 169
        }
3 paul 170
        return QSpinBox::eventFilter(ob, ev);
171
}
172
 
173
QString MSpinBox::mapValueToText(int value)
174
{
5448 cbradney 175
        QString s;
176
        s.setNum(static_cast<double>(value) / Decimals, 'f', Width);
177
        return s;
3 paul 178
}
179
 
180
int MSpinBox::mapTextToValue(bool *)
181
{
161 Franz 182
        FunctionParser fp;
4110 cbradney 183
        setFPConstants(fp);
138 Franz 184
        QString ts = text();
286 Franz 185
        QString su = suffix().stripWhiteSpace();
138 Franz 186
        ts.replace(",", ".");
272 Franz 187
        ts.replace("%", "");
4944 fschmid 188
        int pos = ts.length();
189
        while (pos > 0)
190
        {
191
                pos = ts.findRev(".", pos);
6004 cbradney 192
                if (pos >= 0)
4944 fschmid 193
                {
194
                        if (pos < static_cast<int>(ts.length()))
195
                        {
196
                                if (!ts[pos+1].isDigit())
197
                                        ts.insert(pos+1, "0 ");
198
                        }
199
                        pos--;
200
                }
201
        }
202
        if (ts.endsWith("."))
203
                ts.append("0");
6004 cbradney 204
 
4114 cbradney 205
        //Get all our units strings
4539 cbradney 206
        QString trStrPT=unitGetStrFromIndex(SC_PT);
207
        QString trStrMM=unitGetStrFromIndex(SC_MM);
208
        QString trStrIN=unitGetStrFromIndex(SC_IN);
209
        QString trStrP =unitGetStrFromIndex(SC_P);
210
        QString trStrCM=unitGetStrFromIndex(SC_CM);
211
        QString trStrC =unitGetStrFromIndex(SC_C);
212
        QString strPT=unitGetUntranslatedStrFromIndex(SC_PT);
213
        QString strMM=unitGetUntranslatedStrFromIndex(SC_MM);
214
        QString strIN=unitGetUntranslatedStrFromIndex(SC_IN);
215
        QString strP =unitGetUntranslatedStrFromIndex(SC_P);
216
        QString strCM=unitGetUntranslatedStrFromIndex(SC_CM);
217
        QString strC =unitGetUntranslatedStrFromIndex(SC_C);
218
        //CB FParser doesn't handle unicode well/at all.
219
        //So, instead of just getting the translated strings and
220
        //sticking them in as variables in the parser, if they are
221
        //not the same as the untranslated version, then we replace them.
6004 cbradney 222
        //We lose the ability for now to have some strings in languages
4539 cbradney 223
        //that might use them in variables.
224
        //To return to previous functionality, remove the follow replacement ifs,
6004 cbradney 225
        //S&R in the trStr* assignments trStrPT->strPT and remove the current str* ones.
4539 cbradney 226
        //IE, send the translated strings through to the regexp.
227
        if (trStrPT.localeAwareCompare(strPT)!=0)
228
                ts.replace(trStrPT, strPT);
229
        if (trStrMM.localeAwareCompare(strMM)!=0)
230
                ts.replace(trStrMM, strMM);
231
        if (trStrIN.localeAwareCompare(strIN)!=0)
232
                ts.replace(trStrIN, strIN);
233
        if (trStrP.localeAwareCompare(strP)!=0)
234
                ts.replace(trStrP, strP);
235
        if (trStrCM.localeAwareCompare(strCM)!=0)
236
                ts.replace(trStrCM, strCM);
8440 jghali 237
        if (trStrC.localeAwareCompare(strC)!=0)
4539 cbradney 238
                ts.replace(trStrC, strC);
4114 cbradney 239
        //Replace in our typed text all of the units strings with *unitstring
4112 cbradney 240
        QRegExp rx("\\b(\\d+)\\s*("+strPT+"|"+strP+"|"+strMM+"|"+strC+"|"+strCM+"|"+strIN+")\\b");
4944 fschmid 241
        pos = 0;
4112 cbradney 242
        while (pos >= 0) {
243
                pos = rx.search(ts, pos);
244
                if (pos >= 0) {
245
                        QString replacement = rx.cap(1) + "*" + rx.cap(2);
246
                        ts.replace(pos, rx.cap(0).length(), replacement);
247
                }
248
        }
4114 cbradney 249
        //Get the index of our suffix
250
        int toConvertToIndex=unitIndexFromString(su);
251
        //Add in the fparser constants using our unit strings, and the conversion factors.
8440 jghali 252
        fp.AddConstant(strPT.local8Bit().data(), value2value(1.0, SC_PT, toConvertToIndex));
253
        fp.AddConstant(strMM.local8Bit().data(), value2value(1.0, SC_MM, toConvertToIndex));
254
        fp.AddConstant(strIN.local8Bit().data(), value2value(1.0, SC_IN, toConvertToIndex));
255
        fp.AddConstant(strP.local8Bit().data(), value2value(1.0, SC_P, toConvertToIndex));
256
        fp.AddConstant(strCM.local8Bit().data(), value2value(1.0, SC_CM, toConvertToIndex));
257
        fp.AddConstant(strC.local8Bit().data(), value2value(1.0, SC_C, toConvertToIndex));
161 Franz 258
        int ret = fp.Parse(ts.latin1(), "", true);
137 Franz 259
        if (ret >= 0)
260
                return 0;
161 Franz 261
        double erg = fp.Eval(NULL);
139 Franz 262
        return qRound(erg*Decimals);
3 paul 263
}
264
 
1617 fschmid 265
void MSpinBox::textChanged()
266
{
267
        edited = true;
268
}
269
 
270
void MSpinBox::stepDown()
271
{
272
        if ( edited )
273
                QSpinBox::interpretText();
274
        if ( wrapping() && ( QSpinBox::value()-lineStep() < QSpinBox::minValue() ) )
275
                QSpinBox::setValue( QSpinBox::maxValue() - (QSpinBox::maxValue() % lineStep()));
276
        else
277
                QSpinBox::subtractLine();
278
}
279
 
333 Franz 280
void MSpinBox::setValues(double min, double max, int deci, double val)
281
{
282
        setDecimals(deci);
283
        setMinValue(min);
284
        setMaxValue(max);
285
        setValue(val);
1617 fschmid 286
        edited = false;
333 Franz 287
}
288
 
289
void MSpinBox::getValues(double *min, double *max, int *deci, double *val)
290
{
291
        *deci = Decimals;
292
        *min = static_cast<double>(QSpinBox::minValue()) / Decimals;
293
        *max = static_cast<double>(QSpinBox::maxValue()) / Decimals;
294
        *val = static_cast<double>(QSpinBox::value()) / Decimals;
295
}
296
 
3 paul 297
void MSpinBox::setDecimals(int deci)
298
{
299
        Decimals = deci;
146 Franz 300
        QSpinBox::setLineStep(Decimals);
138 Franz 301
        if (deci < 10)
302
                Width = 0;
199 Franz 303
        if ((deci > 9) && (deci < 100))
3 paul 304
                Width = 1;
199 Franz 305
        if ((deci > 99) && (deci < 1000))
3 paul 306
                Width = 2;
199 Franz 307
        if ((deci > 999) && (deci < 10000))
139 Franz 308
                Width = 3;
309
        if (deci > 9999)
310
                Width = 4;
3 paul 311
}
146 Franz 312
 
313
void MSpinBox::setMaxValue(double val)
314
{
315
        QSpinBox::setMaxValue(qRound(val*Decimals));
316
}
317
 
318
void MSpinBox::setMinValue(double val)
319
{
320
        QSpinBox::setMinValue(qRound(val*Decimals));
321
}
322
 
323
void MSpinBox::setValue(double val)
324
{
325
        QSpinBox::setValue(qRound(val*Decimals));
1617 fschmid 326
        edited = false;
146 Franz 327
}
328
 
329
double MSpinBox::value()
330
{
331
        return static_cast<double>(QSpinBox::value()) / Decimals;
332
}
199 Franz 333
 
334
double MSpinBox::minValue()
335
{
336
        return static_cast<double>(QSpinBox::minValue()) / Decimals;
337
}
338
 
339
double MSpinBox::maxValue()
340
{
341
        return static_cast<double>(QSpinBox::maxValue()) / Decimals;
342
}
333 Franz 343
 
344
void MSpinBox::setReadOnly( bool ro )
345
{
6004 cbradney 346
        if (readOnly!=ro)
335 Franz 347
        {
333 Franz 348
                if (!readOnly && ro) {
349
                        oldLineStep=QSpinBox::lineStep();
350
                        QSpinBox::setLineStep( 0 );
351
                }
352
                else if (readOnly && !ro) {
353
                        QSpinBox::setLineStep( oldLineStep );
354
                        oldLineStep=0;
355
                }
356
                ed->setReadOnly( ro );
335 Franz 357
                readOnly=ro;
333 Franz 358
        }
359
}
360
 
361
bool MSpinBox::isReadOnly() const
362
{
363
        return readOnly;
364
}
365
 
4110 cbradney 366
void MSpinBox::setConstants(const QMap<QString, double>& newConstants)
367
{
368
        functionParserConstants=newConstants;
369
}
370
 
371
void MSpinBox::setFPConstants(FunctionParser &fp)
372
{
373
        if (functionParserConstants.isEmpty())
374
                return;
6004 cbradney 375
 
4115 cbradney 376
        fp.AddConstant("old", static_cast<double>(QSpinBox::value()) / Decimals);
4110 cbradney 377
        QMap<QString, double>::Iterator itend=functionParserConstants.end();
378
        QMap<QString, double>::Iterator it=functionParserConstants.begin();
379
        while(it!=itend)
380
        {
8440 jghali 381
                fp.AddConstant(it.key().local8Bit().data(), it.data());
4110 cbradney 382
                ++it;
383
        }
384
}