/*************************************************************************** * Copyright (C) 2005 Tobi Vollebregt * * tobivollebregt@gmail.com * * * * Copyright (C) 2005 by Joe Ferris * * jferris@optimistictech.com * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ #include #include #include #include #include #include #include #include "calculatorcatalog.h" #include "expression.h" #include "katapultitem.h" #include "actionevalexpr.h" // Conditional compilation to not bloat the lib if // KDE already has the following functions. // Prevents a deprecated function warning too. #if !KDE_IS_VERSION(3, 5, 0) // Copied some code from KDE 3.5 to make it compile on 3.4. // insert (thousands)-"separator"s into the non-fractional part of str static void _insertSeparator(TQString &str, const TQString &separator, const TQString &decimalSymbol) { // leave fractional part untouched TQString mainPart = str.section(decimalSymbol, 0, 0); TQString fracPart = str.section(decimalSymbol, 1, 1, TQString::SectionIncludeLeadingSep); if (fracPart==decimalSymbol) fracPart=TQString(); for (int pos = mainPart.length() - 3; pos > 0; pos -= 3) mainPart.insert(pos, separator); str = mainPart + fracPart; } // This was KLocale::formatNumber(const TQString&, bool, int) static TQString formatNumber(const TQString &numStr) { TQString tmpString = numStr; // Skip the sign (for now) bool neg = (tmpString[0] == '-'); if (neg || tmpString[0] == '+') tmpString.remove(0, 1); // Split off exponential part (including 'e'-symbol) TQString mantString = tmpString.section('e', 0, 0, TQString::SectionCaseInsensitiveSeps); TQString expString = tmpString.section('e', 1, 1, TQString::SectionCaseInsensitiveSeps | TQString::SectionIncludeLeadingSep); if (expString.length()==1) expString=TQString(); // Replace dot with locale decimal separator mantString.replace(TQChar('.'), KGlobal::locale()->decimalSymbol()); // Insert the thousand separators _insertSeparator(mantString, KGlobal::locale()->thousandsSeparator(), KGlobal::locale()->decimalSymbol()); // How can we know where we should put the sign? mantString.prepend(neg?KGlobal::locale()->negativeSign():KGlobal::locale()->positiveSign()); return mantString + expString; } #else // TDE_VERSION >= 3.5.0 static TQString formatNumber(const TQString& numStr) { return KGlobal::locale()->formatNumber(numStr, false, 0); } #endif ActionEvaluateExpression::ActionEvaluateExpression() : KatapultAction(), _expr(0) { } ActionEvaluateExpression::~ActionEvaluateExpression() { } TQString ActionEvaluateExpression::text() const { if (_expr->parseError()) { return i18n("Evaluate Expression"); } else { // Format result. int digits = _expr->catalog()->fracDigits(); TQChar f = _expr->catalog()->scientific() ? 'g' : 'f'; TQString num = TQString::number(_expr->result(), f, digits); // Strip trailing zeroes. if (f == 'f' && digits != 0) { while (num.endsWith("0")) { num = num.left(num.length() - 1); } if (num.endsWith(".")) { num = num.left(num.length() - 1); } } // Localize (choose right implementation based on KDE version, see above). return formatNumber(num); } } TQPixmap ActionEvaluateExpression::icon(int size) const { return KGlobal::iconLoader()->loadIcon("xcalc", KIcon::NoGroup, size); } bool ActionEvaluateExpression::accepts(const KatapultItem* item) const { bool accept = strcmp(item->className(), "Expression") == 0; if (accept) { _expr = (const Expression*)item; } return accept; } void ActionEvaluateExpression::execute(const KatapultItem* item) const { if (strcmp(item->className(), "Expression") == 0) { _expr = (const Expression*)item; //evaluate expression with assignments enabled _expr->evaluate(true); // Copy calculation and result into clipboard (unless there's a parse error). if (!_expr->parseError()) { TQClipboard *cb = TQApplication::clipboard(); TQString s = _expr->catalog()->formatString(); s.replace("%1", _expr->text()); s.replace("%2", text()); cb->setText(s, TQClipboard::Clipboard); cb->setText(s, TQClipboard::Selection); } } }