~ubuntu-branches/ubuntu/precise/kalzium/precise

« back to all changes in this revision

Viewing changes to plasmoid/applet/nuclearPlasmoid/nuclearCalculator.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Philip Muškovac
  • Date: 2011-07-03 12:28:58 UTC
  • Revision ID: james.westby@ubuntu.com-20110703122858-q1yyxncs89e4w0hs
Tags: upstream-4.6.90+repack
Import upstream version 4.6.90+repack

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
    copyright            : (C) 2009 by Kashyap R Puranik
 
3
    email                : kashthealien@gmail.com
 
4
 ***************************************************************************/
 
5
/***************************************************************************
 
6
 *                                                                         *
 
7
 *   This program is free software; you can redistribute it and/or modify  *
 
8
 *   it under the terms of the GNU General Public License as published by  *
 
9
 *   the Free Software Foundation; either version 2 of the License, or     *
 
10
 *   (at your option) any later version.                                   *
 
11
 *                                                                         *
 
12
 ***************************************************************************/
 
13
#include "nuclearCalculator.h"
 
14
#include <QPainter>
 
15
#include <QFontMetrics>
 
16
#include <QApplication>
 
17
#include <QGridLayout>
 
18
#include <QPushButton>
 
19
#include <QRadioButton>
 
20
#include <KTextEdit>
 
21
#include <QSlider>
 
22
#include <QSpinBox>
 
23
#include <KIntSpinBox>
 
24
#include <KComboBox>
 
25
#include <QSizeF>
 
26
#include <QLabel>
 
27
#include <Plasma/ComboBox>
 
28
#include <Plasma/LineEdit>
 
29
#include <Plasma/Label>
 
30
#include <Plasma/Frame>
 
31
#include <Plasma/RadioButton>
 
32
#include <Plasma/SpinBox>
 
33
#include <Plasma/Slider>
 
34
#include <Plasma/GroupBox>
 
35
#include <Plasma/PushButton>
 
36
#include <QGraphicsGridLayout>
 
37
#include <QGraphicsLinearLayout>
 
38
#include <plasma/svg.h>
 
39
#include <plasma/theme.h>
 
40
#include <math.h>
 
41
 
 
42
#include <KConfigDialog>
 
43
 
 
44
using namespace KUnitConversion;
 
45
 
 
46
nuclearCalculator::nuclearCalculator(QObject *parent, const QVariantList &args)
 
47
: Plasma::PopupApplet(parent, args)
 
48
, m_widget(0)
 
49
{
 
50
    KGlobal::locale()->insertCatalog( "libkdeedu" );
 
51
    m_converter = new Converter( this );
 
52
    setAspectRatioMode(Plasma::IgnoreAspectRatio);
 
53
    setPopupIcon("accessories-calculator");
 
54
    setHasConfigurationInterface(true);
 
55
    setAssociatedApplication("kalzium");
 
56
    resize(600, 450);
 
57
}
 
58
 
 
59
nuclearCalculator::~nuclearCalculator()
 
60
{
 
61
    if (hasFailedToLaunch()) {
 
62
        // Do some cleanup here
 
63
    } else {
 
64
        // Save settings
 
65
    }
 
66
}
 
67
 
 
68
void nuclearCalculator::init()
 
69
{
 
70
    configChanged();
 
71
}
 
72
 
 
73
void nuclearCalculator::configChanged()
 
74
{
 
75
    KConfigGroup cg = config();
 
76
 
 
77
    m_massOnly = cg.readEntry("massOnly",true);
 
78
}
 
79
 
 
80
void nuclearCalculator::reset()
 
81
{
 
82
        const int ISOTOPE_NUM = 22;
 
83
        error(RESET_NUKE_MESG);
 
84
 
 
85
    // Add all isotope names of Uranium ( by default )to the isotope comboBox
 
86
    QList<Isotope*> list = KalziumDataObject::instance()->isotopes(92);
 
87
    QString iso;
 
88
 
 
89
    m_isotope->clear();
 
90
    foreach(Isotope * i , list) {
 
91
        iso.setNum(i->mass());
 
92
        m_isotope->addItem(iso);
 
93
    }
 
94
 
 
95
        // initialize the data, initially selected values ( Uranium, 92, 238)
 
96
    m_element->nativeWidget()-> setCurrentIndex(91);
 
97
    m_isotope->nativeWidget()-> setCurrentIndex(ISOTOPE_NUM);
 
98
    m_halfLife->setValue(list.at(ISOTOPE_NUM) -> halflife());
 
99
    m_initAmt->setValue(6.0);
 
100
    m_finalAmt->setValue(3.0);
 
101
    m_time->setValue(list.at(ISOTOPE_NUM)->halflife());
 
102
 
 
103
    m_halfLifeUnit->nativeWidget()->setCurrentIndex(0);
 
104
    m_initType->nativeWidget()->setCurrentIndex(0);
 
105
    m_finalType->nativeWidget()->setCurrentIndex(0);
 
106
    m_initUnit->nativeWidget()->setCurrentIndex(0);
 
107
    m_finalUnit->nativeWidget()->setCurrentIndex(0);
 
108
    m_timeUnit->nativeWidget()->setCurrentIndex(0);
 
109
    m_calculationMode  ->nativeWidget()->setCurrentIndex(2);
 
110
 
 
111
    // Setup of the UI done
 
112
    // Initialize values
 
113
    m_InitAmount  = Value(6.0, "g") ;
 
114
    m_FinalAmount = Value(3.0, "g");
 
115
    m_Mass = list.at(ISOTOPE_NUM) -> mass();
 
116
    m_Time = Value((list.at(ISOTOPE_NUM) -> halflife()), "y");
 
117
    m_HalfLife = Value(list.at(ISOTOPE_NUM) -> halflife(), "y");
 
118
 
 
119
    m_Element = * KalziumDataObject::instance() -> element(92);
 
120
    m_Isotope = * list.at(ISOTOPE_NUM);
 
121
 
 
122
    setMode(2);
 
123
    // Initialization of values done
 
124
}
 
125
 
 
126
QGraphicsWidget *nuclearCalculator::graphicsWidget()
 
127
{
 
128
//FIXME:
 
129
// Currently the spin boxes are integer, please convert them into double after
 
130
// doubleSpinBoxes are available
 
131
 
 
132
    if (!m_widget) {
 
133
        // Position all UI elements
 
134
        m_widget = new QGraphicsWidget(this);
 
135
        Plasma::Frame *pHeader = new Plasma::Frame(this);
 
136
        pHeader->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
 
137
        pHeader->setText(i18n("Nuclear Calculator"));
 
138
 
 
139
        Plasma::GroupBox *pGroupBox1 = new Plasma::GroupBox(this);
 
140
        Plasma::GroupBox *pGroupBox2 = new Plasma::GroupBox(this);
 
141
 
 
142
        QGraphicsGridLayout *pGridLayout = new QGraphicsGridLayout(pGroupBox1);
 
143
        QGraphicsGridLayout *pGridLayout2 = new QGraphicsGridLayout(pGroupBox2);
 
144
        QGraphicsLinearLayout *pVLayout = new QGraphicsLinearLayout(Qt::Vertical,m_widget);
 
145
        pVLayout->addItem(pGroupBox1);
 
146
        pVLayout->addItem(pGroupBox2);
 
147
        // pVLayout->addItem(new Plasma::)
 
148
 
 
149
        // here comes the element - isotope and halfLife info part
 
150
        Plasma::Label *eleLabel = new Plasma::Label(this);
 
151
        eleLabel->nativeWidget()->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 
152
        eleLabel->setText(i18n("Element name:"));
 
153
        Plasma::Label *isoLabel = new Plasma::Label(this);
 
154
        isoLabel->nativeWidget()->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 
155
        isoLabel->setText(i18n("Isotope mass:"));
 
156
        Plasma::Label *hLifeLabel = new Plasma::Label(this);
 
157
        hLifeLabel->nativeWidget()->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 
158
        hLifeLabel->setText(i18n("Half-Life"));
 
159
 
 
160
        m_element = new Plasma::ComboBox(this);
 
161
        m_element->setZValue(2);
 
162
        m_isotope = new Plasma::ComboBox(this);
 
163
        m_isotope->setZValue(1);
 
164
 
 
165
        m_halfLife = new Plasma::SpinBox(this);
 
166
        m_halfLife->nativeWidget()->setMinimumWidth(100);
 
167
        m_halfLife->nativeWidget()->setMaximum(1000000000);
 
168
        //m_halfLife->setDecimals(4);
 
169
        m_halfLife->setMaximum(1e+09);
 
170
 
 
171
        m_halfLifeUnit = new Plasma::ComboBox(this);
 
172
        m_halfLifeUnit->nativeWidget()->insertItems(0, QStringList()
 
173
         << i18n("year")
 
174
         << i18n("seconds")
 
175
         << i18n("minutes")
 
176
         << i18n("hours")
 
177
         << i18n("days")
 
178
         << i18n("weeks"));
 
179
        m_halfLifeUnit->setZValue(6);
 
180
 
 
181
        pGridLayout->addItem(pHeader, 0, 0, 1, 4);
 
182
        pGridLayout->addItem(eleLabel, 1, 0);
 
183
        pGridLayout->addItem(m_element, 1, 1);
 
184
        pGridLayout->addItem(isoLabel, 2, 0);
 
185
        pGridLayout->addItem(m_isotope, 2, 1);
 
186
        pGridLayout->addItem(hLifeLabel, 3, 0);
 
187
        pGridLayout->addItem(m_halfLifeUnit, 3, 2);
 
188
        pGridLayout->addItem(m_halfLife, 3, 1);
 
189
 
 
190
        // Here comes the amount and time part
 
191
 
 
192
        // Calculation mode
 
193
        Plasma::Label *calcModeLabel = new Plasma::Label(this);
 
194
        calcModeLabel->nativeWidget()->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 
195
        calcModeLabel->setText(i18n("Calculation Mode:"));
 
196
 
 
197
        m_calculationMode = new Plasma::ComboBox(this);
 
198
        m_calculationMode->setZValue(3);
 
199
        m_calculationMode->nativeWidget()->insertItems(0, QStringList()
 
200
            << i18n("Initial amount")
 
201
            << i18n("Final amount")
 
202
            << i18n("Time")
 
203
        );
 
204
 
 
205
        Plasma::Label *initLabel = new Plasma::Label(this);
 
206
        initLabel->nativeWidget()->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 
207
        initLabel->setText(i18n("Initial amount:"));
 
208
        Plasma::Label *finalLabel = new Plasma::Label(this);
 
209
        finalLabel->nativeWidget()->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 
210
        finalLabel->setText(i18n("Final amount:"));
 
211
        Plasma::Label *timeLabel = new Plasma::Label(this);
 
212
        timeLabel->nativeWidget()->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 
213
        timeLabel->setText(i18n("Time"));
 
214
/*x     Plasma::Label *m_sliderLabel = new Plasma::Label(this);
 
215
        m_sliderLabel->nativeWidget()->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 
216
        m_sliderLabel->setText(i18n("Time in Half-Lives"));*/
 
217
 
 
218
        m_numHalfLives = new Plasma::Label(this);
 
219
        m_numHalfLives->nativeWidget()->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 
220
        m_numHalfLives->setText(i18n("0 seconds"));
 
221
        m_initAmt = new Plasma::SpinBox(this);
 
222
        m_initAmt->nativeWidget()->setMinimumWidth(200);
 
223
        m_initAmt->nativeWidget()->setMaximum(1000000000);
 
224
        //m_initAmt->setDecimals(4);
 
225
        m_initAmt->setMaximum(1e+09);
 
226
        m_finalAmt = new Plasma::SpinBox(this);
 
227
        m_finalAmt->nativeWidget()->setMinimumWidth(200);
 
228
        m_finalAmt->nativeWidget()->setMaximum(1000000000);
 
229
        //m_finalAmt->setDecimals(4);
 
230
        m_finalAmt->setMaximum(1e+09);
 
231
        m_time = new Plasma::SpinBox(this);
 
232
        m_time->nativeWidget()->setMinimumWidth(200);
 
233
        m_time->nativeWidget()->setMaximum(1000000000);
 
234
        //m_time->setDecimals(4);
 
235
        m_time->setMaximum(1e+09);
 
236
 
 
237
        m_initUnit = new Plasma::ComboBox(this);
 
238
        m_initUnit->setZValue(2);
 
239
        m_initUnit->nativeWidget()->insertItems(0, QStringList()
 
240
         << i18n("grams")
 
241
         << i18n("tons")
 
242
         << i18n("carats")
 
243
         << i18n("pounds")
 
244
         << i18n("ounces")
 
245
         << i18n("troy ounces"));
 
246
        m_initUnit->setZValue(3);
 
247
 
 
248
        m_finalUnit = new Plasma::ComboBox(this);
 
249
        m_finalUnit->setZValue(2);
 
250
        m_finalUnit->nativeWidget()->insertItems(0, QStringList()
 
251
         << i18n("grams")
 
252
         << i18n("tons")
 
253
         << i18n("carats")
 
254
         << i18n("pounds")
 
255
         << i18n("ounces")
 
256
         << i18n("troy ounces"));
 
257
        m_finalUnit->setZValue(2);
 
258
 
 
259
        m_timeUnit = new Plasma::ComboBox(this);
 
260
        m_timeUnit->setZValue(2);
 
261
        m_timeUnit->nativeWidget()->insertItems(0, QStringList()
 
262
         << i18n("year")
 
263
         << i18n("seconds")
 
264
         << i18n("minutes")
 
265
         << i18n("hours")
 
266
         << i18n("days")
 
267
         << i18n("weeks"));
 
268
        m_timeUnit->setZValue(1);
 
269
 
 
270
        m_initType = new Plasma::ComboBox(this);
 
271
        m_initType->setZValue(2);
 
272
        m_initType->nativeWidget()->insertItems(0, QStringList()
 
273
         << i18n("Mass")
 
274
         << i18n("moles"));
 
275
        m_initType->setZValue(2);
 
276
 
 
277
        m_finalType = new Plasma::ComboBox(this);
 
278
        m_finalType->setZValue(2);
 
279
        m_finalType->nativeWidget()->insertItems(0, QStringList()
 
280
         << i18n("Mass")
 
281
         << i18n("moles"));
 
282
                m_finalType->setZValue(1);
 
283
 
 
284
        /*m_slider = new Plasma::Slider(this);
 
285
        m_slider->setRange(0, 100);
 
286
        m_slider->setOrientation(Qt::Horizontal);
 
287
        m_slider->setMaximum(100); */
 
288
 
 
289
        m_error = new Plasma::Label(this);
 
290
 
 
291
        m_reset = new Plasma::PushButton(this);
 
292
        m_reset->setText(i18n("Reset"));
 
293
 
 
294
        pGridLayout2->addItem(calcModeLabel, 5, 0);
 
295
        pGridLayout2->addItem(initLabel, 6, 0);
 
296
        pGridLayout2->addItem(finalLabel, 7, 0);
 
297
        pGridLayout2->addItem(timeLabel, 8, 0);
 
298
//          pGridLayout2->addItem(m_sliderLabel, 9, 0);
 
299
        pGridLayout2->addItem(m_error, 10, 1, 1, 3);
 
300
        pGridLayout2->addItem(m_reset, 10, 0);
 
301
 
 
302
        pGridLayout2->addItem(m_calculationMode, 5, 1);
 
303
        pGridLayout2->addItem(m_initAmt, 6, 1);
 
304
        pGridLayout2->addItem(m_finalAmt, 7, 1);
 
305
        pGridLayout2->addItem(m_time, 8, 1);
 
306
//          pGridLayout2->addItem(m_slider , 9, 1);
 
307
 
 
308
        pGridLayout2->addItem(m_initType, 6, 3);
 
309
        pGridLayout2->addItem(m_finalType, 7, 3);
 
310
        pGridLayout2->addItem(m_numHalfLives, 9, 2);
 
311
 
 
312
        pGridLayout2->addItem(m_initUnit, 6, 2);
 
313
        pGridLayout2->addItem(m_finalUnit, 7, 2);
 
314
        pGridLayout2->addItem(m_timeUnit, 8, 2);
 
315
 
 
316
        // Positioning of UI elements done
 
317
        // Now add required properties to the UI widgets
 
318
 
 
319
        /**************************************************************************/
 
320
        //                       Nuclear Calculator set up                        //
 
321
        /**************************************************************************/
 
322
        KalziumDataObject *kdo = KalziumDataObject::instance();
 
323
 
 
324
        // add all element names to the comboBox in the user interface
 
325
        foreach(Element * e, kdo -> ElementList) {
 
326
            m_element->nativeWidget()->addItem(e -> dataAsString(ChemicalDataObject::name));
 
327
        }
 
328
            ///FIXME
 
329
        /* The last three elements will be removed because information is not available
 
330
            and causes the program to crash when selected. */
 
331
        int count = m_element->nativeWidget()->count();
 
332
        m_element->nativeWidget()->removeItem(count - 1);
 
333
        m_element->nativeWidget()->removeItem(count - 2);
 
334
        m_element->nativeWidget()->removeItem(count - 3);
 
335
        // Add all isotope names of Uranium ( by default )to the isotope comboBox
 
336
        reset();
 
337
 
 
338
        // Connect signals with slots
 
339
        connect(m_element->nativeWidget(), SIGNAL(activated(int)),
 
340
                this, SLOT(elementChanged(int)));
 
341
        connect(m_isotope->nativeWidget(), SIGNAL(activated(int)),
 
342
                this, SLOT(isotopeChanged(int)));
 
343
//FIXME change int to double in the following signals after finding doubleSpinBox
 
344
        connect(m_halfLife, SIGNAL(valueChanged(int)),
 
345
                    this, SLOT(halfLifeChanged()));
 
346
        connect(m_halfLifeUnit->nativeWidget(), SIGNAL(activated(int)),
 
347
                this, SLOT(halfLifeChanged()));
 
348
        connect(m_initAmt, SIGNAL(valueChanged(int)),
 
349
                this, SLOT(initAmtChanged()));
 
350
        connect(m_initUnit->nativeWidget(), SIGNAL(activated(int)),
 
351
                this, SLOT(initAmtChanged()));
 
352
        connect(m_initType->nativeWidget(), SIGNAL(activated(int)),
 
353
                this, SLOT(initAmtChanged()));
 
354
        connect(m_finalAmt, SIGNAL(valueChanged(int)),
 
355
                this, SLOT(finalAmtChanged()));
 
356
        connect(m_finalUnit->nativeWidget(), SIGNAL(activated(int)),
 
357
                this, SLOT(finalAmtChanged()));
 
358
        connect(m_finalType->nativeWidget(), SIGNAL(activated(int)),
 
359
                this, SLOT(finalAmtChanged()));
 
360
        connect(m_time, SIGNAL(valueChanged(int)),
 
361
                this, SLOT(timeChanged()));
 
362
        connect(m_timeUnit->nativeWidget(), SIGNAL(activated(int)),
 
363
                this, SLOT(timeChanged()));
 
364
/*          connect(m_slider, SIGNAL(valueChanged(int)),
 
365
                this, SLOT(sliderMoved(int)));*/
 
366
        connect(m_calculationMode->nativeWidget(), SIGNAL(activated(int)),
 
367
                        this, SLOT(setMode(int)));
 
368
        connect(m_reset, SIGNAL(clicked()),
 
369
                        this, SLOT(reset()));
 
370
        /**************************************************************************/
 
371
        // Nuclear Calculator setup complete
 
372
        /**************************************************************************/
 
373
        }
 
374
    return m_widget;
 
375
}
 
376
 
 
377
void nuclearCalculator::elementChanged (int index)
 
378
{
 
379
    // set the newly chosen element
 
380
    m_Element = * KalziumDataObject::instance()-> element(index + 1);
 
381
 
 
382
    // Add all isotope names of Uranium ( by default ) to the isotope comboBox
 
383
    QList<Isotope*> list = KalziumDataObject::instance()-> isotopes(index + 1);
 
384
    QString isotope;                        // A temporary string
 
385
    m_isotope  -> clear();               // Clear the contents of the combo box
 
386
    // update the combobox with isotopes of the new element
 
387
    foreach(Isotope * i , list) {
 
388
        isotope.setNum(i -> mass());
 
389
        m_isotope-> addItem(isotope);
 
390
    }
 
391
 
 
392
    // Set the halfLife to that of the first isotope of the element.
 
393
    m_halfLife-> setValue(list. at(0)-> halflife());
 
394
    // Recalculate and update
 
395
    calculate();
 
396
}
 
397
 
 
398
void nuclearCalculator::isotopeChanged(int index)
 
399
{
 
400
    // update the nuclear Calculator
 
401
    int elementNumber = m_element->nativeWidget()-> currentIndex() + 1;
 
402
    QList<Isotope*> list = KalziumDataObject::instance() -> isotopes(elementNumber);
 
403
    m_Isotope = * list.at(index);
 
404
 
 
405
    // get the halfLife of the new isotope
 
406
    double halfLife = list . at(index) -> halflife();
 
407
    m_Mass = list.at(index)-> mass();
 
408
 
 
409
    // A string used for searching the right Unit
 
410
    QString halfLifeUnit = list . at(index) -> halflifeUnit();
 
411
    halfLifeUnit = (halfLifeUnit == "y") ? "year" : "seconds";
 
412
 
 
413
    // Update the UI with the halfLife value
 
414
    m_halfLife-> setValue(halfLife);
 
415
    int x = m_halfLifeUnit->nativeWidget()-> findText(halfLifeUnit);
 
416
    if (x >= 0)
 
417
        m_halfLifeUnit->nativeWidget()-> setCurrentIndex(x);
 
418
    m_HalfLife = Value(halfLife, halfLifeUnit);
 
419
    // Recalculate and update
 
420
    calculate();
 
421
}
 
422
 
 
423
void nuclearCalculator::halfLifeChanged()
 
424
{
 
425
    // update the halfLife value
 
426
    m_HalfLife = Value(m_halfLife -> value(), m_halfLifeUnit->nativeWidget()-> currentText());
 
427
    // recalculate the required
 
428
    calculate();
 
429
}
 
430
 
 
431
void nuclearCalculator::initAmtChanged()
 
432
{
 
433
 
 
434
    // If quantity is specified in terms of mass, quantity <- ( mass , Unit)
 
435
    if (m_initType->nativeWidget() -> currentIndex() == 0)
 
436
        m_InitAmount = Value(m_initAmt -> value(), m_initUnit->nativeWidget() -> currentText());
 
437
 
 
438
    // If quantity is specified in terms of moles quantity <- ( moles * atomicMass, Unit )
 
439
    else
 
440
        m_InitAmount = Value(((m_initAmt -> value()) * m_Mass), \
 
441
                             m_initUnit->nativeWidget()-> currentText());
 
442
 
 
443
        calculate();
 
444
}
 
445
 
 
446
void nuclearCalculator::finalAmtChanged()
 
447
{
 
448
    // If quantity is specified in terms of mass, quantity <- ( mass , Unit)
 
449
    if (m_finalType->nativeWidget() -> currentIndex() == 0) {
 
450
        m_FinalAmount = Value(m_finalAmt -> value(), \
 
451
                              m_finalUnit->nativeWidget()-> currentText());
 
452
    // If quantity is specified in terms of moles quantity <- ( moles * atomicMass, Unit )
 
453
    } else {
 
454
        m_FinalAmount = Value(((m_finalAmt -> value()) * m_Mass), \
 
455
                              m_finalUnit->nativeWidget() -> currentText());
 
456
    }
 
457
 
 
458
    calculate();
 
459
}
 
460
 
 
461
void nuclearCalculator::timeChanged()
 
462
{
 
463
    m_Time = Value(m_time-> value(), m_timeUnit->nativeWidget()-> currentText());
 
464
 
 
465
    calculate();
 
466
}
 
467
 
 
468
/*void nuclearCalculator::sliderMoved(int numHlives)
 
469
{
 
470
    double num = numHlives / 10.0;
 
471
    m_Time = Value(num * m_HalfLife. number() , m_HalfLife. unit());
 
472
 
 
473
    m_time-> setValue(m_Time. number());
 
474
    m_timeUnit->nativeWidget()-> setCurrentIndex(m_halfLifeUnit->nativeWidget()-> currentIndex());
 
475
    m_numHalfLives-> setText(m_Time . toString());
 
476
}*/
 
477
 
 
478
void nuclearCalculator::calculate()
 
479
{
 
480
    error(RESET_NUKE_MESG);
 
481
    // Validate the values involved in calculation
 
482
    if (m_HalfLife. number() == 0.0) {
 
483
        error(HALFLIFE_ZERO);
 
484
        return;
 
485
    }
 
486
 
 
487
    switch (m_mode) {
 
488
        case 0: // Calculate initial amount
 
489
        if (m_FinalAmount.number() == 0.0) {
 
490
            error(FINAL_AMT_ZERO);
 
491
            return;
 
492
        }
 
493
        calculateInitAmount();
 
494
        break;
 
495
    case 1: // Calulate final Amount after time
 
496
        if (m_InitAmount.number() == 0.0) {
 
497
            error(INIT_AMT_ZERO);
 
498
            return;
 
499
        }
 
500
        calculateFinalAmount();
 
501
        break;
 
502
    case 2: // Calculate Time
 
503
        // If final amount greater than initial, error
 
504
    if (m_FinalAmount.number() > (m_converter->convert(m_InitAmount,
 
505
        m_FinalAmount.unit()->symbol())).number()) {
 
506
            error(FINAL_AMT_GREATER);
 
507
            return;
 
508
        } else if (m_finalAmt-> value() == 0.0)
 
509
        { // final amount is 0.0
 
510
            error(FINAL_AMT_ZERO);
 
511
            return;
 
512
        }
 
513
        calculateTime();
 
514
        break;
 
515
        }
 
516
}
 
517
 
 
518
void nuclearCalculator::setMode(int mode)
 
519
{
 
520
        m_mode = mode;
 
521
 
 
522
        m_initAmt->nativeWidget()->setReadOnly(false);
 
523
        m_finalAmt->nativeWidget()->setReadOnly(false);
 
524
        m_time->nativeWidget()->setReadOnly(false);
 
525
 
 
526
        // set the quantity that should be calculated to readOnly
 
527
        switch (mode)
 
528
        {
 
529
            case 0:
 
530
                m_initAmt->nativeWidget()->setReadOnly(true);
 
531
//                      showSlider(true);
 
532
                break;
 
533
            case 1:
 
534
                m_finalAmt->nativeWidget()->setReadOnly(true);
 
535
//                      showSlider(true);
 
536
                break;
 
537
            case 2:
 
538
                m_time->nativeWidget()->setReadOnly(true);
 
539
//                      showSlider(false);
 
540
                break;
 
541
        }
 
542
 
 
543
        calculate();
 
544
}
 
545
 
 
546
void nuclearCalculator::showSlider(bool show)
 
547
{
 
548
/*      if (show) {
 
549
                m_sliderLabel->hide();
 
550
                m_slider->hide();
 
551
                m_numHalfLives->hide();
 
552
        }
 
553
        else {
 
554
                m_sliderLabel->show();
 
555
                m_slider->show();
 
556
                m_numHalfLives->show();
 
557
        }
 
558
*/
 
559
}
 
560
 
 
561
void nuclearCalculator::calculateInitAmount()
 
562
{
 
563
    // If no time has elapsed, initial and final amounts are the same
 
564
    m_InitAmount = m_FinalAmount;
 
565
    if (m_Time. number() == 0.0) {
 
566
        m_initAmt-> setValue(m_InitAmount . number());
 
567
        return;
 
568
    }
 
569
    // Calculate the number of halfLives that have elapsed
 
570
    double ratio = (m_converter->convert(m_Time, m_HalfLife. unit() \
 
571
                    ->symbol()). number()) /m_HalfLife. number();
 
572
    // find out the initial amount
 
573
    m_InitAmount = Value(m_InitAmount. number() * pow(2.0 , ratio), m_InitAmount. unit());
 
574
    // Convert into the required units
 
575
    m_InitAmount = m_converter->convert(m_InitAmount, m_InitAmount. unit()->symbol());
 
576
    m_initAmt-> setValue(m_InitAmount . number());
 
577
}
 
578
 
 
579
void nuclearCalculator::calculateFinalAmount()
 
580
{
 
581
    // If no time has elapsed, initial and final amounts are the same
 
582
    m_FinalAmount = m_InitAmount;
 
583
    if (m_Time. number() == 0.0) {
 
584
            m_finalAmt-> setValue(m_FinalAmount. number());
 
585
        return;
 
586
    }
 
587
    // Calculate the number of halfLives that have elapsed
 
588
    double ratio = (m_converter->convert(m_Time , m_HalfLife. unit() \
 
589
                    ->symbol()). number()) / m_HalfLife. number();
 
590
    // Calculate the final amount
 
591
    m_FinalAmount = Value(m_FinalAmount . number() / pow(2.0, ratio), m_InitAmount. unit());
 
592
    // Convert into the required units
 
593
    m_FinalAmount = m_converter->convert(m_FinalAmount, m_FinalAmount. unit()->symbol());
 
594
    m_finalAmt-> setValue(m_FinalAmount. number());
 
595
}
 
596
 
 
597
void nuclearCalculator::calculateTime()
 
598
{
 
599
    // If initial and final masses are the same ( both units and value )
 
600
    // the time is also 0
 
601
    if (m_InitAmount.number() == m_FinalAmount.number() && \
 
602
            m_InitAmount. unit() == m_FinalAmount . unit()) {
 
603
        m_Time = Value(0.0, m_Time. unit());
 
604
        m_time-> setValue(m_Time. number());
 
605
        return;
 
606
    }
 
607
 
 
608
    // calculate the ratio of final to initial masses
 
609
    double ratio = (m_converter->convert(m_InitAmount , m_FinalAmount.unit()\
 
610
                                ->symbol())).number() / m_FinalAmount.number();
 
611
    // The number of halfLives ( log 2 ( x ) = log x / log 2 )
 
612
    double numHalfLives = log(ratio) / log(2.0);
 
613
    double time_value = numHalfLives  * m_HalfLife . number();
 
614
    // Calculate the total time taken
 
615
    Value temp = Value(time_value, m_HalfLife. unit());
 
616
    m_Time = m_converter->convert(temp , m_Time.unit()->symbol());
 
617
    m_time-> setValue(m_Time. number());
 
618
}
 
619
 
 
620
void nuclearCalculator::error( int mode)
 
621
{
 
622
    switch (mode) { // Depending on the mode, set the error messages.
 
623
        case RESET_NUKE_MESG:
 
624
            m_error->setText("");
 
625
            break;
 
626
        case INIT_AMT_ZERO:
 
627
            m_error->setText(i18n("Initial amount cannot be zero."));
 
628
            break;
 
629
        case FINAL_AMT_ZERO:
 
630
            m_error->setText(i18n("Final amount cannot be zero."));
 
631
            break;
 
632
        case HALFLIFE_ZERO:
 
633
            m_error->setText(i18n("Time is zero, please enter a valid value."));
 
634
            break;
 
635
        case FINAL_AMT_GREATER:
 
636
            m_error->setText(i18n("Final amount cannot be greater than initial amount."));
 
637
            break;
 
638
    }
 
639
}
 
640
 
 
641
void nuclearCalculator::createConfigurationInterface(KConfigDialog *parent)
 
642
{
 
643
    QWidget *widget = new QWidget();
 
644
    ui.setupUi(widget);
 
645
    parent->addPage(widget, i18n("General"), icon());
 
646
 
 
647
    ui.massOnly->setChecked(m_massOnly);
 
648
    
 
649
    connect ( parent, SIGNAL ( applyClicked() ), this, SLOT ( configAccepted() ) );
 
650
    connect ( parent, SIGNAL ( okClicked() ), this, SLOT ( configAccepted() ) );
 
651
    connect (ui.massOnly, SIGNAL(toggled(bool)), parent, SLOT(settingsModified()));
 
652
}
 
653
 
 
654
void nuclearCalculator::configAccepted()
 
655
{
 
656
    KConfigGroup cg = config();
 
657
    QGraphicsItem::update();
 
658
 
 
659
    m_massOnly = ui.massOnly->isChecked();
 
660
    cg.writeEntry("massOnly", m_massOnly);
 
661
 
 
662
    m_configUpdated = true;
 
663
    updateConstraints();
 
664
 
 
665
    emit configNeedsSaving();
 
666
}
 
667
#include "nuclearCalculator.moc"