File indexing completed on 2024-04-21 03:41:37
0001 /* 0002 SPDX-FileCopyrightText: 2009 Kashyap R Puranik <kashthealien@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "concCalculator.h" 0008 0009 0010 #include <KLocalizedString> 0011 0012 #include "kalziumutils.h" 0013 #include "prefs.h" 0014 0015 using namespace KUnitConversion; 0016 0017 concCalculator::concCalculator(QWidget *parent) 0018 : QFrame(parent) 0019 { 0020 ui.setupUi(this); 0021 0022 /**************************************************************************/ 0023 // concentration Calculator set up 0024 /**************************************************************************/ 0025 0026 // initialise the initially selected values 0027 init(); 0028 0029 // Connect signals with slots (when a change of selection in the UI takes place, 0030 // corresponding quantity should be updated in the class.) 0031 0032 // Amount of solute changed 0033 connect(ui.amtSolute, SIGNAL(valueChanged(double)), this, SLOT(amtSoluteChanged())); 0034 connect(ui.amtSltType, SIGNAL(activated(int)), this, SLOT(amtSoluteTypeChanged())); 0035 connect(ui.amtSlt_unit, SIGNAL(activated(int)), this, SLOT(amtSoluteChanged())); 0036 // Molar mass and equivalent mass change for solvent 0037 connect(ui.molarMass, SIGNAL(valueChanged(double)), this, SLOT(molarMassChanged(double))); 0038 connect(ui.eqtMass, SIGNAL(valueChanged(double)), this, SLOT(eqtMassChanged(double))); 0039 // Density change for solute 0040 connect(ui.densitySolute, SIGNAL(valueChanged(double)), this, SLOT(densitySoluteChanged())); 0041 connect(ui.densSlt_unit, SIGNAL(activated(int)), this, SLOT(densitySoluteChanged())); 0042 // Amount of solvent changed 0043 connect(ui.amtSolvent, SIGNAL(valueChanged(double)), this, SLOT(amtSolventChanged())); 0044 connect(ui.amtSlvtType, SIGNAL(activated(int)), this, SLOT(amtSolventTypeChanged())); 0045 connect(ui.amtSlvt_unit, SIGNAL(activated(int)), this, SLOT(amtSolventChanged())); 0046 // Molar mass change for solvent 0047 connect(ui.molarMassSolvent, SIGNAL(valueChanged(double)), this, SLOT(molarMassSolventChanged(double))); 0048 // Density changed 0049 connect(ui.densitySolvent, SIGNAL(valueChanged(double)), this, SLOT(densitySolventChanged())); 0050 connect(ui.densSlvt_unit, SIGNAL(activated(int)), this, SLOT(densitySolventChanged())); 0051 // concentration change 0052 connect(ui.concentration, SIGNAL(valueChanged(double)), this, SLOT(concentrationChanged())); 0053 connect(ui.conc_unit, SIGNAL(activated(int)), this, SLOT(concentrationChanged())); 0054 // Mode change 0055 connect(ui.mode, SIGNAL(activated(int)), this, SLOT(setMode(int))); 0056 0057 connect(ui.reset, &QAbstractButton::clicked, this, &concCalculator::init); 0058 0059 /**************************************************************************/ 0060 // concentration Calculator setup complete 0061 /**************************************************************************/ 0062 if (Prefs::soluteMass()) { 0063 ui.amtSltType->setCurrentIndex(0); 0064 } 0065 if (Prefs::solventVolume()) { 0066 ui.amtSlvtType->setCurrentIndex(0); 0067 } 0068 } 0069 0070 concCalculator::~concCalculator() = default; 0071 0072 // Initialises values and GUI. 0073 void concCalculator::init() 0074 { 0075 error(RESET_CONC_MESSAGE); 0076 0077 ui.amtSltType->addItems({"Mass", "Volume", "Moles"}); 0078 ui.amtSlvtType->addItems({"Volume", "Mass", "Moles"}); 0079 ui.densSlt_unit->addItems({"grams per liter"}); 0080 ui.densSlvt_unit->addItems({"grams per liter"}); 0081 ui.conc_unit->addItems({"molar", "Normal", "% (mass)", "% (volume)", "% (moles)"}); 0082 0083 amtSoluteTypeChanged(); 0084 amtSolventTypeChanged(); 0085 0086 ui.amtSolute->setValue(117.0); 0087 ui.molarMass->setValue(58.5); 0088 ui.eqtMass->setValue(58.5); 0089 ui.densitySolute->setValue(2.7); 0090 ui.amtSolvent->setValue(1.0); 0091 ui.molarMassSolvent->setValue(18.0); 0092 ui.densitySolvent->setValue(1000.0); 0093 ui.concentration->setValue(2.0); 0094 0095 ui.amtSltType->setCurrentIndex(0); 0096 ui.amtSlt_unit->setCurrentIndex(0); 0097 ui.densSlt_unit->setCurrentIndex(0); 0098 ui.amtSlvtType->setCurrentIndex(0); 0099 ui.amtSlvt_unit->setCurrentIndex(0); 0100 ui.densSlvt_unit->setCurrentIndex(0); 0101 ui.conc_unit->setCurrentIndex(0); 0102 0103 // Initialise values 0104 m_amtSolute = Value(117.0, KUnitConversion::Gram); 0105 m_amtSolvent = Value(1.0, KUnitConversion::Liter); 0106 m_molarMass = 58.5; 0107 m_eqtMass = 58.5; 0108 m_molesSolute = 2.0; 0109 m_molesSolvent = 55.5; 0110 m_molarMassSolvent = 18.0; 0111 m_densitySolute = Value(2.7, KUnitConversion::GramPerMilliliter); 0112 m_concentration = 2.0; 0113 m_densitySolvent = Value(1000.0, KUnitConversion::GramPerLiter); 0114 // Initialisation of values done 0115 0116 setMode(5); 0117 } 0118 0119 // Calculates the amount of solute 0120 void concCalculator::calculateAmtSolute() 0121 { 0122 int type1 = ui.conc_unit->currentIndex(); 0123 int type2 = ui.amtSltType->currentIndex(); 0124 0125 double molesSolute, eqtsSolute, massSolute, volSolute; // variables 0126 int mode = 0; 0127 /* 0128 * mode = 1 (molesSolute) mode = 2 eqtsSolute, mode = 3 mass, 4 volume 0129 */ 0130 // Calculate the number of moles of the solute 0131 switch (type1) { 0132 // calculate the number of moles of solute 0133 case 0: // molarity specified 0134 molesSolute = m_concentration * volumeSolvent(); 0135 mode = 1; 0136 break; 0137 // Calculate the number of equivalents of solute 0138 case 1: // Normality specified 0139 eqtsSolute = m_concentration * volumeSolvent(); 0140 mode = 2; 0141 break; 0142 // Calculate the number of moles of solute 0143 case 2: // molality specified 0144 molesSolute = m_concentration * massSolvent() / 1000.0; 0145 mode = 1; 0146 break; 0147 // Calculate the mass of solute 0148 case 3: // mass percentage specified 0149 if (m_concentration >= 100.0) { 0150 error(PERCENTAGE); 0151 } 0152 massSolute = m_concentration / (100.0 - m_concentration) * massSolvent(); 0153 mode = 3; 0154 break; 0155 // Calculate the volume of solute 0156 case 4: // volume percentage specified 0157 if (m_concentration >= 100.0) { 0158 error(PERCENTAGE); 0159 } 0160 volSolute = m_concentration / (100.0 - m_concentration) * volumeSolvent(); 0161 mode = 4; 0162 break; 0163 // Calculate the moles of solute 0164 case 5: // mole percentage specified 0165 if (m_concentration >= 100.0) { 0166 error(PERCENTAGE); 0167 } 0168 molesSolute = m_concentration / (100.0 - m_concentration) * molesSolvent(); 0169 mode = 1; 0170 break; 0171 default: 0172 break; 0173 } 0174 0175 // We have the amount of solvent in some form (moles, equivalents, mass, volume etc) 0176 // Now we have to present it in the UI 0177 switch (type2) { 0178 case 0: // amount should be specified in terms of mass 0179 switch (mode) { 0180 case 1: // we should get mass from moles 0181 massSolute = molesSolute * m_molarMass; 0182 break; 0183 case 2: // we should obtain mass from number of equivalents 0184 massSolute = eqtsSolute * m_eqtMass; 0185 break; 0186 case 3: // we already know the mass of the solute 0187 break; 0188 case 4: // we should get the mass from volume 0189 massSolute = volSolute * densitySolute(); 0190 break; 0191 } 0192 // update mass of solute 0193 m_amtSolute = Value(massSolute, KUnitConversion::Gram); 0194 m_amtSolute = m_amtSolute.convertTo(ui.amtSlt_unit->currentText()); 0195 ui.amtSolute->setValue(m_amtSolute.number()); 0196 break; 0197 0198 case 1: // amount should be specified in terms of volume 0199 // validate density 0200 if (densitySolute() == 0) { 0201 error(DENSITY_ZERO); 0202 return; 0203 } 0204 switch (mode) { 0205 case 1: // we should get the volume from moles 0206 volSolute = molesSolute * m_molarMass / densitySolute(); 0207 break; 0208 case 2: // we should get the volume from equivalents 0209 volSolute = eqtsSolute * m_eqtMass / densitySolute(); 0210 break; 0211 case 3: // we should get the volume from mass 0212 volSolute = massSolute / densitySolute(); 0213 break; 0214 case 4: // we already know the volume 0215 break; 0216 } 0217 // update volume of solute 0218 m_amtSolute = Value(volSolute, KUnitConversion::Liter); 0219 m_amtSolute = m_amtSolute.convertTo(ui.amtSlt_unit->currentText()); 0220 ui.amtSolute->setValue(m_amtSolute.number()); 0221 break; 0222 0223 case 2: // amount should be specified in terms of moles 0224 switch (mode) { 0225 case 1: // we already know the moles of solute 0226 break; 0227 case 2: // we should obtain moles from equivalents (not possible) 0228 molesSolute = 0.0; 0229 break; 0230 case 3: // we should obtain moles from mass 0231 molesSolute = massSolute / m_molarMass; 0232 break; 0233 case 4: // we should obtain moles from volume 0234 molesSolute = volSolute * densitySolute() / m_molarMass; 0235 break; 0236 } 0237 // Update the number of moles 0238 m_molesSolute = molesSolute; 0239 ui.amtSolute->setValue(molesSolute); 0240 break; 0241 } 0242 return; 0243 } 0244 0245 // Calculates the molar mass 0246 void concCalculator::calculateMolarMass() 0247 { 0248 // molarity / molality / mole fraction required 0249 int type = ui.conc_unit->currentIndex(); 0250 int type2 = ui.amtSlvtType->currentIndex(); 0251 double numMoles; 0252 switch (type) { 0253 case 0: // molarity specified 0254 // number of moles = volume * concentration 0255 numMoles = volumeSolvent() * m_concentration; 0256 break; 0257 case 1: // cannot be calculated (insufficient data) 0258 error(INSUFFICIENT_DATA_MOLE); 0259 return; 0260 case 2: // molality specified 0261 numMoles = massSolvent() / 1000.0 * m_concentration; 0262 break; 0263 case 3: // cannot be calculated (insufficient data) 0264 case 4: 0265 error(INSUFFICIENT_DATA_MOLE); 0266 return; 0267 case 5: // mole fraction specified 0268 numMoles = m_concentration / (100.0 - m_concentration) * molesSolvent(); 0269 break; 0270 } 0271 0272 if (type2 == 2) { // amount of solute is specified in moles, cannot calculate 0273 error(INSUFFICIENT_DATA_MOLES); 0274 return; 0275 } else { 0276 if (numMoles == 0.0) { 0277 error(MOLES_ZERO); 0278 return; 0279 } 0280 m_molarMass = massSolute() / numMoles; 0281 ui.molarMass->setValue(m_molarMass); 0282 } 0283 } 0284 0285 // Calculates the equivalent mass 0286 void concCalculator::calculateEqtMass() 0287 { 0288 // Normality required 0289 int type = ui.conc_unit->currentIndex(); 0290 int type2 = ui.amtSltType->currentIndex(); 0291 0292 double numEqts; 0293 switch (type) { 0294 // Normality required 0295 case 0: // molarity not sufficient 0296 error(INSUFFICIENT_DATA_EQT); 0297 return; 0298 case 1: // normality specified 0299 numEqts = volumeSolvent() * m_concentration; 0300 break; 0301 case 2: 0302 case 3: 0303 case 4: 0304 case 5: 0305 error(INSUFFICIENT_DATA_EQT); 0306 return; 0307 } 0308 0309 if (type2 == 2) { // Amount of solute specified in moles, cannot calculate 0310 error(INSUFFICIENT_DATA_MOLES); 0311 } else { 0312 if (numEqts == 0.0) { 0313 error(EQTS_ZERO); 0314 return; 0315 } 0316 m_eqtMass = massSolute() / numEqts; 0317 ui.eqtMass->setValue(m_eqtMass); 0318 } 0319 return; 0320 } 0321 0322 // Calculates the calculate molar mass of the solvent 0323 void concCalculator::calculateMolarMassSolvent() 0324 { 0325 // molarity / molality / mole fraction required 0326 int type = ui.conc_unit->currentIndex(); 0327 int type2 = ui.amtSlvtType->currentIndex(); 0328 double numMoles; 0329 switch (type) { 0330 case 0: // molarity specified 0331 case 1: // normality specified 0332 case 2: // molality specified 0333 case 3: // mass fraction specified 0334 case 4: // volume fraction specified 0335 error(INSUFFICIENT_DATA_SOLVENT); 0336 return; // cannot be calculated (insufficient data) 0337 case 5: // mole fraction specified 0338 numMoles = (100.0 - m_concentration) / m_concentration * molesSolute(); 0339 break; 0340 } 0341 0342 if (type2 == 2) { // amount specified in moles 0343 error(INSUFFICIENT_DATA_MOLES); 0344 } else { 0345 m_molarMassSolvent = massSolvent() / numMoles; 0346 ui.molarMassSolvent->setValue(m_molarMassSolvent); 0347 } 0348 0349 return; 0350 } 0351 0352 // Calculates the amount of solvent 0353 void concCalculator::calculateAmtSolvent() 0354 { 0355 int type1 = ui.conc_unit->currentIndex(); 0356 int type2 = ui.amtSlvtType->currentIndex(); 0357 0358 double moleSolvent, massSolvent, volSolvent; 0359 0360 int mode = 0; // Indicates the mode in which we have calculated the amount of solvent 0361 /* 0362 * mode = 1 (molessolvent) mode = 2 eqtssolvent, mode = 3 mass, 4 volume 0363 */ 0364 // Calculate the number of moles of the solvent 0365 if (m_concentration == 0.0) { 0366 error(CONC_ZERO); 0367 return; 0368 } 0369 0370 switch (type1) { 0371 // calculate the number of moles of solvent 0372 case 0: // molarity specified 0373 volSolvent = molesSolute() / m_concentration; 0374 mode = 3; 0375 break; 0376 // Calculate the number of equivalents of solvent 0377 case 1: // Normality specified 0378 volSolvent = eqtsSolute() / m_concentration; 0379 mode = 3; 0380 break; 0381 // Calculate the number of moles of solvent 0382 case 2: // molality specified 0383 massSolvent = molesSolute() * 1000.0 / m_concentration; 0384 mode = 2; 0385 break; 0386 // Calculate the mass of solvent 0387 case 3: // mass percentage specified 0388 massSolvent = (100.0 - m_concentration) / m_concentration; 0389 massSolvent *= massSolute(); 0390 mode = 2; 0391 break; 0392 // Calculate the volume of solvent 0393 case 4: // volume percentage specified 0394 volSolvent = (100.0 - m_concentration) / m_concentration; 0395 volSolvent *= volumeSolute(); 0396 mode = 3; 0397 break; 0398 // Calculate the moles of solvent 0399 case 5: // mole percentage specified 0400 moleSolvent = (100.0 - m_concentration) / m_concentration; 0401 moleSolvent *= molesSolute(); 0402 mode = 1; 0403 break; 0404 default: 0405 break; 0406 } 0407 0408 // We have the amount of solvent in some form (moles, equivalents, mass, volume etc) 0409 // Now we have to present it in the UI 0410 if (densitySolvent() == 0.0) { 0411 error(DENSITY_ZERO); 0412 return; 0413 } 0414 if (m_molarMassSolvent == 0.0) { 0415 error(MOLAR_SOLVENT_ZERO); 0416 return; 0417 } 0418 switch (type2) { 0419 case 0: // amount should be specified interms of volume 0420 switch (mode) { 0421 case 1: // obtain volume from moles 0422 volSolvent = moleSolvent * m_molarMassSolvent / densitySolvent(); 0423 break; 0424 case 2: // obtain volume from mass 0425 volSolvent = massSolvent / densitySolvent(); 0426 break; 0427 case 3: // volume already known 0428 break; 0429 } 0430 m_amtSolvent = Value(volSolvent, KUnitConversion::Liter); 0431 m_amtSolvent = m_amtSolvent.convertTo(ui.amtSlvt_unit->currentText()); 0432 ui.amtSolvent->setValue(m_amtSolvent.number()); 0433 break; 0434 0435 case 1: // amount should be specified in terms of mass 0436 switch (mode) { 0437 case 1: // obtain mass from moles 0438 massSolvent = moleSolvent / m_molarMassSolvent; 0439 break; 0440 case 2: // mass already known 0441 break; 0442 case 3: // obtain mass from volume 0443 massSolvent = volSolvent / densitySolvent(); 0444 break; 0445 } 0446 m_amtSolvent = Value(massSolvent, KUnitConversion::Gram); 0447 m_amtSolvent = m_amtSolvent.convertTo(ui.amtSlvt_unit->currentText()); 0448 ui.amtSolvent->setValue(m_amtSolvent.number()); 0449 break; 0450 0451 case 2: // amount should be specified in terms of moles 0452 switch (mode) { 0453 case 1: // moles already known 0454 break; 0455 case 2: // obtain moles from mass 0456 moleSolvent = massSolvent / m_molarMassSolvent; 0457 break; 0458 case 3: // obtain moles from volume 0459 moleSolvent = volSolvent * densitySolvent() / m_molarMassSolvent; 0460 break; 0461 } 0462 m_molesSolvent = moleSolvent; 0463 ui.amtSolvent->setValue(moleSolvent); 0464 break; 0465 } 0466 return; 0467 } 0468 0469 // calculates the concentration 0470 void concCalculator::calculateConcentration() 0471 { 0472 int type = ui.conc_unit->currentIndex(); 0473 0474 if (volumeSolvent() == 0.0) { 0475 error(SOLVENT_VOLUME_ZERO); 0476 return; 0477 } 0478 if (massSolvent() == 0.0) { 0479 error(SOLVENT_MASS_ZERO); 0480 return; 0481 } 0482 if (molesSolvent() == 0.0) { 0483 error(SOLVENT_MOLES_ZERO); 0484 return; 0485 } 0486 switch (type) { 0487 case 0: // molarity 0488 m_concentration = molesSolute() / volumeSolvent(); 0489 break; 0490 case 1: // normality 0491 m_concentration = eqtsSolute() / volumeSolvent(); 0492 break; 0493 case 2: // molality 0494 m_concentration = molesSolute() * 1000.0 / massSolvent(); 0495 break; 0496 case 3: // mass fraction 0497 m_concentration = massSolute() / (massSolute() + massSolvent()) * 100.0; 0498 break; 0499 case 4: // volume fraction 0500 m_concentration = volumeSolute() / (volumeSolute() + volumeSolvent()) * 100.0; 0501 break; 0502 case 5: // mole fraction 0503 m_concentration = molesSolute() / (molesSolute() + molesSolvent()) * 100.0; 0504 break; 0505 default: 0506 m_concentration = 0; 0507 break; 0508 } 0509 ui.concentration->setValue(m_concentration); 0510 return; 0511 } 0512 0513 double concCalculator::volumeSolvent() 0514 { 0515 int type = ui.amtSlvtType->currentIndex(); 0516 switch (type) { 0517 case 0: // If volume is specified, return it in liters 0518 return m_amtSolvent.convertTo(KUnitConversion::Liter).number(); 0519 case 1: // If mass is specified, calculate volume and return it. 0520 return massSolvent() / densitySolvent(); 0521 case 2: // If moles are specified, calculated volume and return it. 0522 return massSolvent() / densitySolvent(); 0523 default: 0524 return 0; 0525 } 0526 Q_UNREACHABLE(); 0527 } 0528 0529 double concCalculator::molesSolvent() 0530 { 0531 int type = ui.amtSlvtType->currentIndex(); 0532 0533 double moles; 0534 switch (type) { 0535 case 0: 0536 moles = massSolvent() / m_molarMassSolvent; 0537 break; 0538 case 1: 0539 moles = massSolvent() / m_molarMassSolvent; 0540 break; 0541 case 2: 0542 moles = m_molesSolvent; 0543 break; 0544 default: 0545 moles = 0; 0546 break; 0547 } 0548 return moles; 0549 } 0550 double concCalculator::massSolvent() 0551 { 0552 int type = ui.amtSlvtType->currentIndex(); 0553 double mass; 0554 switch (type) { 0555 case 0: 0556 mass = volumeSolvent() * densitySolvent(); 0557 break; 0558 case 1: 0559 mass = m_amtSolvent.convertTo(KUnitConversion::Gram).number(); 0560 break; 0561 case 2: 0562 mass = m_molesSolvent * m_molarMassSolvent; 0563 break; 0564 default: 0565 mass = 0; 0566 break; 0567 } 0568 return mass; 0569 } 0570 0571 double concCalculator::densitySolvent() 0572 { 0573 return (m_densitySolvent.convertTo(KUnitConversion::GramPerLiter).number()); 0574 } 0575 0576 double concCalculator::volumeSolute() 0577 { 0578 int type = ui.amtSltType->currentIndex(); 0579 double volume; 0580 switch (type) { 0581 case 0: 0582 volume = massSolute() / densitySolute(); 0583 break; 0584 case 1: 0585 volume = m_amtSolute.convertTo(KUnitConversion::Liter).number(); 0586 break; 0587 case 2: 0588 volume = massSolute() / densitySolute(); 0589 break; 0590 default: 0591 volume = 0; 0592 break; 0593 } 0594 return volume; 0595 } 0596 0597 double concCalculator::molesSolute() 0598 { 0599 int type = ui.amtSltType->currentIndex(); 0600 0601 double moles; 0602 if (m_molarMass == 0.0) { 0603 error(MOLAR_MASS_ZERO); 0604 return 1.0; 0605 } 0606 switch (type) { 0607 case 0: 0608 moles = massSolute() / m_molarMass; 0609 break; 0610 case 1: 0611 moles = massSolute() / m_molarMass; 0612 break; 0613 case 2: 0614 moles = m_molesSolute; 0615 break; 0616 default: 0617 moles = 0; 0618 break; 0619 } 0620 return moles; 0621 } 0622 0623 double concCalculator::eqtsSolute() 0624 { 0625 int type = ui.amtSltType->currentIndex(); 0626 double eqts; 0627 if (m_eqtMass == 0.0) { 0628 error(EQT_MASS_ZERO); 0629 return 1.0; 0630 } 0631 switch (type) { 0632 case 0: 0633 eqts = massSolute() / m_eqtMass; 0634 break; 0635 case 1: 0636 eqts = massSolute() / m_eqtMass; 0637 break; 0638 case 2: 0639 // Cannot be calculated 0640 error(INSUFFICIENT_DATA_MOLES); 0641 eqts = 1.0; 0642 break; 0643 default: 0644 eqts = 0; 0645 break; 0646 } 0647 return eqts; 0648 } 0649 0650 double concCalculator::massSolute() 0651 { 0652 int type = ui.amtSltType->currentIndex(); 0653 double mass; 0654 switch (type) { 0655 case 0: 0656 mass = m_amtSolute.convertTo(KUnitConversion::Gram).number(); 0657 break; 0658 case 1: 0659 mass = volumeSolute() * densitySolute(); 0660 break; 0661 case 2: 0662 mass = m_molesSolute * m_molarMass; 0663 break; 0664 default: 0665 mass = 0; 0666 break; 0667 } 0668 return mass; 0669 } 0670 0671 double concCalculator::densitySolute() 0672 { 0673 return (m_densitySolute.convertTo(KUnitConversion::GramPerLiter).number()); 0674 } 0675 0676 // occurs when the type in which amount of solute is specified is changed 0677 void concCalculator::amtSoluteTypeChanged() 0678 { 0679 int type = ui.amtSltType->currentIndex(); 0680 if (type == 0) { 0681 // amount of solute specified in terms of mass 0682 massUnitCombobox(ui.amtSlt_unit); 0683 0684 m_amtSolute = Value(ui.amtSolute->value(), ui.amtSlt_unit->currentText()); 0685 } else if (type == 1) { 0686 // amount of solute is specified in terms of volume 0687 volumeUnitCombobox(ui.amtSlt_unit); 0688 0689 m_amtSolute = Value(ui.amtSolute->value(), ui.amtSlt_unit->currentText()); 0690 } else { // amount of solute is specified in terms of moles 0691 m_molesSolute = ui.amtSolute->value(); 0692 ui.amtSlt_unit->hide(); 0693 } 0694 calculate(); 0695 } 0696 0697 void concCalculator::massUnitCombobox(QComboBox *comboBox) 0698 { 0699 comboBox->show(); 0700 0701 QList<int> units; 0702 units << Gram << Milligram << Kilogram << Ton << Carat << Pound << Ounce << TroyOunce; 0703 KalziumUtils::populateUnitCombobox(comboBox, units); 0704 0705 comboBox->setCurrentIndex(0); 0706 } 0707 0708 void concCalculator::volumeUnitCombobox(QComboBox *comboBox) 0709 { 0710 comboBox->show(); 0711 0712 QList<int> units; 0713 units << Liter << Milliliter << CubicMeter << CubicFoot << CubicInch << CubicMile << FluidOunce << Cup << GallonUS << PintImperial; 0714 KalziumUtils::populateUnitCombobox(comboBox, units); 0715 0716 comboBox->setCurrentIndex(0); 0717 } 0718 0719 void concCalculator::amtSoluteChanged() 0720 { 0721 int type = ui.amtSltType->currentIndex(); 0722 switch (type) { 0723 case 0: 0724 case 1: 0725 m_amtSolute = Value(ui.amtSolute->value(), ui.amtSlt_unit->currentText()); 0726 break; 0727 case 2: 0728 m_molesSolute = ui.amtSolute->value(); 0729 break; 0730 } 0731 calculate(); 0732 } 0733 // occurs when the type in which amount of solvent is specified is changed 0734 void concCalculator::amtSolventTypeChanged() 0735 { 0736 int type = ui.amtSlvtType->currentIndex(); 0737 if (type == 0) { 0738 // amount of solvent specified in terms of volume 0739 volumeUnitCombobox(ui.amtSlvt_unit); 0740 0741 m_amtSolvent = Value(ui.amtSolvent->value(), ui.amtSlvt_unit->currentText()); 0742 } else if (type == 1) { 0743 // amount of solvent is specified in terms of mass 0744 massUnitCombobox(ui.amtSlvt_unit); 0745 0746 m_amtSolvent = Value(ui.amtSolvent->value(), ui.amtSlvt_unit->currentText()); 0747 } else { 0748 ui.amtSlvt_unit->hide(); 0749 m_molesSolvent = ui.amtSolvent->value(); 0750 } 0751 calculate(); 0752 } 0753 0754 // Occurs when the amount of solute is changed 0755 void concCalculator::amtSolventChanged() 0756 { 0757 int type = ui.amtSlvtType->currentIndex(); 0758 switch (type) { // amount of solvent specified in terms of volume 0759 case 0: 0760 case 1: 0761 m_amtSolvent = Value(ui.amtSolvent->value(), ui.amtSlvt_unit->currentText()); 0762 break; 0763 case 2: 0764 m_molesSolvent = ui.amtSolvent->value(); 0765 break; 0766 } 0767 calculate(); 0768 } 0769 // occurs when the molar mass of solute is changed 0770 void concCalculator::molarMassChanged(double value) 0771 { 0772 m_molarMass = value; 0773 calculate(); 0774 } 0775 0776 // occurs when the equivalent mass of solute is changed 0777 void concCalculator::eqtMassChanged(double value) 0778 { 0779 m_eqtMass = value; 0780 calculate(); 0781 } 0782 0783 // occurs when the molar mass of solvent is changed 0784 void concCalculator::molarMassSolventChanged(double value) 0785 { 0786 m_molarMassSolvent = value; 0787 calculate(); 0788 } 0789 0790 // occurs when the number of moles is changed 0791 void concCalculator::densitySoluteChanged() 0792 { 0793 m_densitySolute = Value(ui.densitySolute->value(), ui.densSlt_unit->currentText()); 0794 calculate(); 0795 } 0796 0797 // occurs when the density of solvent is changed 0798 void concCalculator::densitySolventChanged() 0799 { 0800 m_densitySolvent = Value(ui.densitySolvent->value(), ui.densSlvt_unit->currentText()); 0801 calculate(); 0802 } 0803 0804 // occurs when the concentration is changed 0805 void concCalculator::concentrationChanged() 0806 { 0807 m_concentration = ui.concentration->value(); 0808 calculate(); 0809 } 0810 0811 // occurs when mode is changed. eg Concentration to molarMass 0812 void concCalculator::setMode(int mode) 0813 { 0814 // If there is no change, return. 0815 if (m_mode == mode) { 0816 return; 0817 } 0818 0819 // set all to writable 0820 ui.amtSolute->setReadOnly(false); 0821 ui.molarMass->setReadOnly(false); 0822 ui.eqtMass->setReadOnly(false); 0823 ui.amtSolvent->setReadOnly(false); 0824 ui.molarMassSolvent->setReadOnly(false); 0825 ui.concentration->setReadOnly(false); 0826 0827 // set the value that should be calculated to readOnly 0828 switch (mode) { 0829 case AMT_SOLUTE: // Calculate the amount of solute 0830 ui.amtSolute->setReadOnly(true); 0831 break; 0832 case MOLAR_MASS: // Calculate the molar mass of solute 0833 ui.molarMass->setReadOnly(true); 0834 break; 0835 case EQT_MASS: // Calculate the equivalent mass of solute 0836 ui.eqtMass->setReadOnly(true); 0837 break; 0838 case AMT_SOLVENT: // Calculate the amount of solvent 0839 ui.amtSolvent->setReadOnly(true); 0840 break; 0841 case MOLAR_MASS_SOLVENT: // Calculate the molar mass of solvent 0842 ui.molarMassSolvent->setReadOnly(true); 0843 break; 0844 case CONCENTRATION: // Calculate the concentration of the solution 0845 ui.concentration->setReadOnly(true); 0846 break; 0847 } 0848 0849 m_mode = mode; 0850 calculate(); 0851 } 0852 // occurs when any quantity is changed 0853 void concCalculator::calculate() 0854 { 0855 error(RESET_CONC_MESSAGE); 0856 // Calculate the amount of solute 0857 switch (m_mode) { 0858 case AMT_SOLUTE: // Calculate the amount of solute 0859 if (ui.conc_unit->currentIndex() > 2 && ui.concentration->value() > 100) { 0860 error(PERCENTAGE); 0861 return; 0862 } 0863 calculateAmtSolute(); 0864 break; 0865 case MOLAR_MASS: // Calculate the molar mass of solute 0866 calculateMolarMass(); 0867 break; 0868 case EQT_MASS: // Calculate the equivalent mass of solute 0869 calculateEqtMass(); 0870 break; 0871 case AMT_SOLVENT: // Calculate the amount of solvent 0872 calculateAmtSolvent(); 0873 break; 0874 case MOLAR_MASS_SOLVENT: // Calculate the molar mass of solvent 0875 calculateMolarMassSolvent(); 0876 break; 0877 case CONCENTRATION: // Calculate the concentration of the solution 0878 calculateConcentration(); 0879 break; 0880 } 0881 return; 0882 } 0883 0884 // This function puts the error messages on the screen depending on the mode. 0885 void concCalculator::error(int mode) 0886 { 0887 switch (mode) { // Depending on the mode, set the error messages. 0888 case RESET_CONC_MESSAGE: 0889 ui.error->setText(QLatin1String("")); 0890 break; 0891 case PERCENTAGE: 0892 ui.error->setText(i18n("Percentage should be less than 100.0, please enter a valid value.")); 0893 break; 0894 case DENSITY_ZERO: 0895 ui.error->setText(i18n("Density cannot be zero, please enter a valid value.")); 0896 break; 0897 case MASS_ZERO: 0898 ui.error->setText(i18n("Mass cannot be zero, please enter a valid value.")); 0899 break; 0900 case VOLUME_ZERO: 0901 ui.error->setText(i18n("Volume cannot be zero, please enter a valid value.")); 0902 break; 0903 case MOLES_ZERO: 0904 ui.error->setText(i18n("Number of moles cannot be zero, please enter a valid value.")); 0905 break; 0906 case MOLAR_SOLVENT_ZERO: 0907 ui.error->setText(i18n("Molar mass of solvent is zero, please enter a valid value.")); 0908 break; 0909 case EQTS_ZERO: 0910 ui.error->setText(i18n("Number of equivalents is zero. Cannot calculate equivalent mass.")); 0911 break; 0912 case CONC_ZERO: 0913 ui.error->setText(i18n("Concentration is zero, please enter a valid value.")); 0914 break; 0915 case SOLVENT_VOLUME_ZERO: 0916 ui.error->setText(i18n("The volume of the solvent cannot be zero.")); 0917 break; 0918 case SOLVENT_MOLES_ZERO: 0919 ui.error->setText(i18n("The number of moles of the solvent cannot be zero.")); 0920 break; 0921 case SOLVENT_MASS_ZERO: 0922 ui.error->setText(i18n("The mass of the solvent cannot be zero.")); 0923 break; 0924 case INSUFFICIENT_DATA_EQT: 0925 ui.error->setText(i18n("Insufficient data to calculate the required value, please specify normality.")); 0926 break; 0927 case INSUFFICIENT_DATA_MOLE: 0928 ui.error->setText(i18n("Insufficient data, specify molarity / mole fraction / molality to calculate.")); 0929 break; 0930 case INSUFFICIENT_DATA_MOLES: 0931 ui.error->setText(i18n("The amount is specified in moles, cannot calculate molar/equivalent masses. Please specify mass/volume.")); 0932 break; 0933 case INSUFFICIENT_DATA_SOLVENT: 0934 ui.error->setText(i18n("You can calculate the molar mass of solvent only if the mole fraction is specified.")); 0935 break; 0936 case MOLAR_MASS_ZERO: 0937 ui.error->setText(i18n("Molar mass cannot be zero, please enter a valid value.")); 0938 break; 0939 case EQT_MASS_ZERO: 0940 ui.error->setText(i18n("Equivalent mass cannot be zero, please enter a valid value.")); 0941 break; 0942 default: 0943 break; 0944 } 0945 } 0946 0947 #include "moc_concCalculator.cpp"