~ubuntu-branches/ubuntu/maverick/scribus-ng/maverick-backports

« back to all changes in this revision

Viewing changes to scribus/scrspinbox.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Oleksandr Moskalenko
  • Date: 2009-02-09 09:25:18 UTC
  • mfrom: (5.1.4 sid)
  • Revision ID: james.westby@ubuntu.com-20090209092518-iqsxmh3pjspgrdyd
Tags: 1.3.5.dfsg~svn20090208-2
debian/control: Use "type-handling -n arm,armel,armeb any" to generate the
list of architectures to build on.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
*/
 
7
/***************************************************************************
 
8
 *   Craig Bradney, cbradney@zip.com.au                                    *
 
9
 ***************************************************************************/
 
10
 
 
11
#include <cmath>
 
12
 
 
13
#include <QtDebug>
 
14
#include <QEvent>
 
15
#include <QKeyEvent>
 
16
#include <QRegExp>
 
17
 
 
18
#include "commonstrings.h"
 
19
#include "scrspinbox.h"
 
20
#include "units.h"
 
21
#include "fparser.h"
 
22
 
 
23
ScrSpinBox::ScrSpinBox(QWidget *parent, int unitIndex) : QDoubleSpinBox(parent), m_constants(NULL)
 
24
{
 
25
        init(unitIndex);
 
26
}
 
27
 
 
28
ScrSpinBox::ScrSpinBox(double minValue, double maxValue, QWidget *pa, int unitIndex) : QDoubleSpinBox(pa), m_constants(NULL)
 
29
{
 
30
        init(unitIndex);
 
31
        setMinimum(minValue);
 
32
        setMaximum(maxValue);
 
33
}
 
34
 
 
35
void ScrSpinBox::init(int unitIndex)
 
36
{
 
37
        m_unitIndex=unitIndex;
 
38
        m_tabAdvance=true;
 
39
        setSuffix(unitGetSuffixFromIndex(m_unitIndex));
 
40
        setDecimals(unitGetPrecisionFromIndex(m_unitIndex));
 
41
        setSingleStep(1.0);
 
42
        lineEdit()->setValidator(0);
 
43
        disconnect(this, SIGNAL(valueChanged(const QString &)), this, SLOT(textChanged()));
 
44
        connect(this, SIGNAL(valueChanged(const QString &)), this, SLOT(textChanged()));
 
45
        installEventFilter(this);
 
46
}
 
47
 
 
48
ScrSpinBox::~ScrSpinBox()
 
49
{
 
50
}
 
51
 
 
52
 
 
53
void ScrSpinBox::setParameters( int s )
 
54
{
 
55
        if (s>=0 && s <=unitGetMaxIndex())
 
56
                setDecimals(static_cast<int>(pow(10.0, s)));
 
57
        else
 
58
                setDecimals(100);
 
59
}
 
60
 
 
61
void ScrSpinBox::setNewUnit(int unitIndex)
 
62
{
 
63
        double oldUnitRatio=unitGetRatioFromIndex(m_unitIndex);
 
64
        double oldVal = value() / oldUnitRatio;
 
65
        double oldMax = maximum() / oldUnitRatio;
 
66
        double oldMin = minimum() / oldUnitRatio;
 
67
        setSuffix(unitGetSuffixFromIndex(unitIndex));
 
68
        setDecimals(unitGetPrecisionFromIndex(unitIndex));
 
69
        double newUnitRatio=unitGetRatioFromIndex(unitIndex);
 
70
        setMinimum(oldMin * newUnitRatio);
 
71
        setMaximum(oldMax * newUnitRatio);
 
72
        setSingleStep(1.0);
 
73
        m_unitIndex=unitIndex;
 
74
        setValue(oldVal * newUnitRatio);
 
75
}
 
76
 
 
77
void ScrSpinBox::setValues(double min, double max, int deci, double val)
 
78
{
 
79
        setDecimals(deci);
 
80
        setMinimum(min);
 
81
        setMaximum(max);
 
82
        setValue(val);
 
83
}
 
84
 
 
85
void ScrSpinBox::getValues(double *min, double *max, int *deci, double *val)
 
86
{
 
87
        *deci = decimals();
 
88
        *min = minimum();
 
89
        *max = maximum();
 
90
        *val = value();
 
91
}
 
92
 
 
93
double ScrSpinBox::getValue(int unitIndex)
 
94
{
 
95
        double val=value() / unitGetRatioFromIndex(m_unitIndex);
 
96
        if (unitIndex==0)
 
97
                return val;
 
98
        return val * unitGetRatioFromIndex(unitIndex);
 
99
}
 
100
 
 
101
void ScrSpinBox::setConstants(const QMap<QString, double>* constants)
 
102
{
 
103
        m_constants = constants;
 
104
}
 
105
 
 
106
 
 
107
 
 
108
static const QString FinishTag("\xA0");
 
109
 
 
110
double ScrSpinBox::valueFromText ( const QString & text ) const
 
111
{
 
112
        //Get all our units strings
 
113
//CB: Replaced by new CommonStrings versions
 
114
//      QString trStrPT=unitGetStrFromIndex(SC_PT);
 
115
//      QString trStrMM=unitGetStrFromIndex(SC_MM);
 
116
//      QString trStrIN=unitGetStrFromIndex(SC_IN);
 
117
//      QString trStrP =unitGetStrFromIndex(SC_P);
 
118
//      QString trStrCM=unitGetStrFromIndex(SC_CM);
 
119
//      QString trStrC =unitGetStrFromIndex(SC_C);
 
120
//      QString strPT=unitGetUntranslatedStrFromIndex(SC_PT);
 
121
//      QString strMM=unitGetUntranslatedStrFromIndex(SC_MM);
 
122
//      QString strIN=unitGetUntranslatedStrFromIndex(SC_IN);
 
123
//      QString strP =unitGetUntranslatedStrFromIndex(SC_P);
 
124
//      QString strCM=unitGetUntranslatedStrFromIndex(SC_CM);
 
125
//      QString strC =unitGetUntranslatedStrFromIndex(SC_C);
 
126
        //Get a copy for use
 
127
        QString ts = text.trimmed();
 
128
        //Find our suffix
 
129
        QString su(unitGetStrFromIndex(m_unitIndex));
 
130
        //Replace our pica XpY.Z format with (X*12+Y.Z)pt
 
131
        if (CommonStrings::trStrP.localeAwareCompare(CommonStrings::strP)!=0)
 
132
                ts.replace(CommonStrings::trStrP, CommonStrings::strP);
 
133
        QRegExp rxP;
 
134
        if (m_unitIndex==SC_PICAS)
 
135
                rxP.setPattern("\\b(\\d+)"+CommonStrings::strP+"?(\\d+\\.?\\d*)?\\b");
 
136
        else
 
137
                rxP.setPattern("\\b(\\d+)"+CommonStrings::strP+"(\\d+\\.?\\d*)?\\b");
 
138
        int posP = 0;
 
139
        while (posP >= 0)
 
140
        {
 
141
//              qDebug() << "#";
 
142
                posP = rxP.indexIn(ts, posP);
 
143
                if (posP >= 0)
 
144
                {
 
145
//                      qDebug() << rxP.cap(1);
 
146
//                      qDebug() << rxP.cap(2);
 
147
                        QString replacement = QString("%1%2").arg(rxP.cap(1).toDouble()*(static_cast<double>(unitGetBaseFromIndex(SC_PICAS))) + rxP.cap(2).toDouble()).arg(CommonStrings::strPT);
 
148
                        ts.replace(posP, rxP.cap(0).length(), replacement);
 
149
//                      qDebug() << ts;
 
150
                }
 
151
        }
 
152
//      qDebug() << "##" << ts;
 
153
        
 
154
        ts.replace(",", ".");
 
155
        ts.replace("%", "");
 
156
        ts.replace("°", "");
 
157
        ts.replace(FinishTag, "");
 
158
        ts = ts.trimmed();
 
159
 
 
160
        if (ts.endsWith(su))
 
161
                ts = ts.left(ts.length()-su.length());
 
162
        int pos = ts.length();
 
163
        while (pos > 0)
 
164
        {
 
165
                pos = ts.lastIndexOf(".", pos);
 
166
                if (pos >= 0) 
 
167
                {
 
168
                        if (pos < static_cast<int>(ts.length()))
 
169
                        {
 
170
                                if (!ts[pos+1].isDigit())
 
171
                                        ts.insert(pos+1, "0 ");
 
172
                        }
 
173
                        pos--;
 
174
                }
 
175
        }
 
176
        if (ts.endsWith("."))
 
177
                ts.append("0");
 
178
        //CB FParser doesn't handle unicode well/at all.
 
179
        //So, instead of just getting the translated strings and
 
180
        //sticking them in as variables in the parser, if they are
 
181
        //not the same as the untranslated version, then we replace them.
 
182
        //We lose the ability for now to have some strings in languages 
 
183
        //that might use them in variables.
 
184
        //To return to previous functionality, remove the follow replacement ifs,
 
185
        //S&R in the trStr* assignments trStrPT->strPT and remove the current str* ones. 
 
186
        //IE, send the translated strings through to the regexp.
 
187
        if (CommonStrings::trStrPT.localeAwareCompare(CommonStrings::strPT)!=0)
 
188
                ts.replace(CommonStrings::trStrPT, CommonStrings::strPT);
 
189
        if (CommonStrings::trStrMM.localeAwareCompare(CommonStrings::strMM)!=0)
 
190
                ts.replace(CommonStrings::trStrMM, CommonStrings::strMM);
 
191
        if (CommonStrings::trStrIN.localeAwareCompare(CommonStrings::strIN)!=0)
 
192
                ts.replace(CommonStrings::trStrIN, CommonStrings::strIN);
 
193
        if (CommonStrings::trStrCM.localeAwareCompare(CommonStrings::strCM)!=0)
 
194
                ts.replace(CommonStrings::trStrCM, CommonStrings::strCM);
 
195
        if (CommonStrings::trStrC.localeAwareCompare(CommonStrings::strPT)!=0)
 
196
                ts.replace(CommonStrings::trStrC, CommonStrings::strC);
 
197
        //Replace in our typed text all of the units strings with *unitstring
 
198
        QRegExp rx("\\b(\\d+)\\s*("+CommonStrings::strPT+"|"+CommonStrings::strMM+"|"+CommonStrings::strC+"|"+CommonStrings::strCM+"|"+CommonStrings::strIN+")\\b");
 
199
        pos = 0;
 
200
        while (pos >= 0) {
 
201
                pos = rx.indexIn(ts, pos);
 
202
                if (pos >= 0) {
 
203
                        QString replacement = rx.cap(1) + "*" + rx.cap(2);
 
204
                        ts.replace(pos, rx.cap(0).length(), replacement);
 
205
                }
 
206
        }
 
207
 
 
208
        //Add in the fparser constants using our unit strings, and the conversion factors.
 
209
        FunctionParser fp;
 
210
//      setFPConstants(fp);
 
211
        fp.AddConstant(CommonStrings::strPT.toStdString(), value2value(1.0, SC_PT, m_unitIndex));
 
212
        fp.AddConstant(CommonStrings::strMM.toStdString(), value2value(1.0, SC_MM, m_unitIndex));
 
213
        fp.AddConstant(CommonStrings::strIN.toStdString(), value2value(1.0, SC_IN, m_unitIndex));
 
214
        fp.AddConstant(CommonStrings::strP.toStdString(), value2value(1.0, SC_P, m_unitIndex));
 
215
        fp.AddConstant(CommonStrings::strCM.toStdString(), value2value(1.0, SC_CM, m_unitIndex));
 
216
        fp.AddConstant(CommonStrings::strC.toStdString(), value2value(1.0, SC_C, m_unitIndex));
 
217
 
 
218
        fp.AddConstant("old", value());
 
219
        if (m_constants)
 
220
        {
 
221
                QMap<QString, double>::ConstIterator itend = m_constants->constEnd();
 
222
                QMap<QString, double>::ConstIterator it = m_constants->constBegin();
 
223
                while(it != itend)
 
224
                {
 
225
                        fp.AddConstant(it.key().toStdString(), it.value() * unitGetRatioFromIndex(m_unitIndex));
 
226
                        ++it;
 
227
                }
 
228
        }
 
229
        
 
230
        int ret = fp.Parse(ts.toStdString(), "", true);
 
231
//      qDebug() << "fp return =" << ret;
 
232
        if (ret >= 0)
 
233
                return 0;
 
234
        double erg = fp.Eval(NULL);
 
235
//      qDebug() << "fp value =" << erg;
 
236
        return erg;
 
237
}
 
238
 
 
239
QString ScrSpinBox::textFromValue ( double value ) const
 
240
{
 
241
        if (m_unitIndex==SC_PICAS)
 
242
        {
 
243
//              QString r=QString("%1%2%3").arg((static_cast<int>(value))/12).arg(unitGetStrFromIndex(m_unitIndex)).arg(fabs(fmod(value, 12)));
 
244
                int a=(static_cast<int>(value))/12;
 
245
                double b=fabs(fmod(value, 12));
 
246
                QString prefix((a==0 && value < 0.0) ? "-" : "");
 
247
                return QString("%1%2%3%4").arg(prefix).arg(a).arg(unitGetStrFromIndex(m_unitIndex)).arg(b);
 
248
        }
 
249
        return QDoubleSpinBox::textFromValue ( value );
 
250
}
 
251
 
 
252
QValidator::State ScrSpinBox::validate ( QString & input, int & pos ) const
 
253
{
 
254
        if (input.endsWith(FinishTag))
 
255
        {
 
256
//              qDebug() << "spinbox validate acceptable:" << input;
 
257
                return QValidator::Acceptable;
 
258
        }
 
259
        else
 
260
        {
 
261
//              qDebug() << "spinbox validate intermediate:" << input;
 
262
                return QValidator::Intermediate;
 
263
        }
 
264
}
 
265
 
 
266
void ScrSpinBox::fixup ( QString & input ) const
 
267
{
 
268
        if (!input.endsWith(FinishTag))
 
269
                input += FinishTag;
 
270
}
 
271
 
 
272
 
 
273
void ScrSpinBox::textChanged()
 
274
{
 
275
//      qDebug() << "v:" << value() << "t:" << text() << "ct:" << cleanText();
 
276
}
 
277
 
 
278
bool ScrSpinBox::eventFilter( QObject* watched, QEvent* event )
 
279
{
 
280
        bool retval = false;
 
281
/* Adding this to be sure that the IM* events are processed correctly i.e not intercepted by our KeyPress/Release handlers */
 
282
        if (event->type() == QEvent::InputMethod)
 
283
                return QDoubleSpinBox::eventFilter(watched, event);
 
284
        /*
 
285
        if ( event->type() == QEvent::KeyPress )
 
286
        {
 
287
                QKeyEvent* k = (QKeyEvent*)event;
 
288
                bool shiftB=k->modifiers() & Qt::ShiftModifier;
 
289
                bool controlB=k->modifiers() & Qt::ControlModifier;
 
290
                if (k->key() == Qt::Key_Shift && !controlB)
 
291
                {
 
292
                        setSingleStep(0.1);
 
293
                        retval = QWidget::event(event);
 
294
                }
 
295
                else if (k->key() == Qt::Key_Control && !shiftB)
 
296
                {
 
297
                        setSingleStep(10.0);
 
298
                        retval = QWidget::event(event);
 
299
                }
 
300
                else if ((k->key() == Qt::Key_Control && shiftB) || (k->key() == Qt::Key_Shift && controlB))
 
301
                {
 
302
                        qDebug("boo1");
 
303
                        setSingleStep(0.01);
 
304
                        retval = QWidget::event(event);
 
305
                }
 
306
                else if ((k->key() == Qt::Key_Return) || (k->key() == Qt::Key_Enter) || (k->key() == Qt::Key_Tab))
 
307
                {
 
308
                        if (!m_tabAdvance)
 
309
                        {
 
310
//                              qDebug() << "eventFilter: interpretText";
 
311
                                QDoubleSpinBox::interpretText();
 
312
                                return true;
 
313
                        }
 
314
                }
 
315
        }
 
316
        else if (event->type() == QEvent::KeyRelease )
 
317
        {
 
318
                QKeyEvent* k = (QKeyEvent*)event;
 
319
                bool shiftB=k->modifiers() & Qt::ShiftModifier;
 
320
                bool controlB=k->modifiers() & Qt::ControlModifier;
 
321
                if ((k->key() == Qt::Key_Shift && !controlB) || (k->key() == Qt::Key_Control && !shiftB))
 
322
                {
 
323
                        setSingleStep(1.0);
 
324
                        retval = QWidget::event(event);
 
325
                }
 
326
                else if (k->key() == Qt::Key_Shift && controlB)
 
327
                {
 
328
                        setSingleStep(10.0);
 
329
                        retval = QWidget::event(event);
 
330
                }
 
331
                else if (k->key() == Qt::Key_Control && shiftB)
 
332
                {
 
333
                        setSingleStep(0.1);
 
334
                        retval = QWidget::event(event);
 
335
                }
 
336
        }
 
337
        */
 
338
        if ( event->type() == QEvent::Wheel )
 
339
        {
 
340
                //If read only dont spin
 
341
                if (isReadOnly())
 
342
                        return false;
 
343
                QWheelEvent* k = (QWheelEvent*)event;
 
344
                bool shiftB=k->modifiers() & Qt::ShiftModifier;
 
345
                bool altB=k->modifiers() & Qt::AltModifier;
 
346
                if (shiftB && !altB)
 
347
                {
 
348
                        setSingleStep(0.1);
 
349
                        retval=QWidget::event(event);
 
350
                } 
 
351
                else if (!shiftB && altB)
 
352
                {
 
353
                        setSingleStep(10.0);
 
354
                        retval=QWidget::event(event);
 
355
                }
 
356
                else if (shiftB && altB)
 
357
                {
 
358
                        setSingleStep(0.01);
 
359
                        retval=QWidget::event(event);
 
360
                }
 
361
                else if (!shiftB && !altB)
 
362
                {
 
363
                        setSingleStep(1.0);
 
364
                        retval=QWidget::event(event);
 
365
                }
 
366
        }
 
367
        else
 
368
                return QDoubleSpinBox::eventFilter(watched, event);
 
369
        return retval;
 
370
}
 
371
 
 
372
// void ScrSpinBox::setSingleStepM(int val)
 
373
// {
 
374
//      QDoubleSpinBox::setSingleStep( val );
 
375
// //   currLineStep = val * Decimals;
 
376
// }
 
377
 
 
378
void ScrSpinBox::setTabAdvance(bool enable)
 
379
{
 
380
        m_tabAdvance = enable;
 
381
}