|
|
|
#include <tqcombobox.h>
|
|
|
|
#include <tqevent.h>
|
|
|
|
#include <tqfile.h>
|
|
|
|
#include <tqguardedptr.h>
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqlineedit.h>
|
|
|
|
#include <tqmap.h>
|
|
|
|
#include <tqpushbutton.h>
|
|
|
|
#include <tqradiobutton.h>
|
|
|
|
#include <tqscrollview.h>
|
|
|
|
#include <tqsizepolicy.h>
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqstringlist.h>
|
|
|
|
#include <tqtextstream.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#include <tqtooltip.h>
|
|
|
|
#include <tqvaluelist.h>
|
|
|
|
#include <tqwhatsthis.h>
|
|
|
|
#include <tqwidget.h>
|
|
|
|
|
|
|
|
#include <tdeaccel.h>
|
|
|
|
#include <tdeaction.h>
|
|
|
|
#include <tdeconfig.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kedittoolbar.h>
|
|
|
|
#include <kdialog.h>
|
|
|
|
#include <tdefiledialog.h>
|
|
|
|
#include <tdeglobal.h>
|
|
|
|
#include <klineedit.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <kkeydialog.h>
|
|
|
|
#include <tdemainwindow.h>
|
|
|
|
#include <knotifyclient.h>
|
|
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <kstatusbar.h>
|
|
|
|
#include <kstdaction.h>
|
|
|
|
#include <tdetoolbar.h>
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include "keypad.h"
|
|
|
|
#include "kparanoidline.h"
|
|
|
|
#include "mathemagics.h"
|
|
|
|
|
|
|
|
Mathemagics::Mathemagics(TQWidget *parent, const char *name, WFlags f)
|
|
|
|
: TDEMainWindow(parent, name, f)
|
|
|
|
{
|
|
|
|
noSave = false;
|
|
|
|
enterMode = false;
|
|
|
|
numStackLevels = 0;
|
|
|
|
stackLevels.setAutoDelete(true);
|
|
|
|
|
|
|
|
TQWidget *dummy = new TQWidget(this);
|
|
|
|
setCentralWidget(dummy);
|
|
|
|
|
|
|
|
TQVBoxLayout *topLayout = new TQVBoxLayout(dummy, 0, KDialog::spacingHint());
|
|
|
|
|
|
|
|
topLevel = new TQScrollView(dummy);
|
|
|
|
topLayout->addWidget(topLevel);
|
|
|
|
|
|
|
|
boxParent = new TQWidget(topLevel->viewport());
|
|
|
|
topLevel->addChild(boxParent);
|
|
|
|
topLevel->setResizePolicy(TQScrollView::AutoOneFit);
|
|
|
|
|
|
|
|
bigBox = new TQVBoxLayout(boxParent, KDialog::marginHint(), KDialog::spacingHint());
|
|
|
|
|
|
|
|
LineEdit = new EditAction(i18n("Values"), 0, this, SLOT(slotEnter()), actionCollection(), "lineedit");
|
|
|
|
HistoryBox = new ComboAction(i18n("History"), 0, 0, 0, actionCollection(), "history");
|
|
|
|
|
|
|
|
keypadAct = new TDEToggleAction(i18n("Show Keypad"), "Ctrl+K", 0, 0, actionCollection(), "keypad");
|
|
|
|
connect(keypadAct, SIGNAL(toggled(bool)), SLOT(toggleKeypad(bool)));
|
|
|
|
|
|
|
|
keypad = new MathKeypad(dummy, "Keypad");
|
|
|
|
topLayout->addWidget(keypad);
|
|
|
|
|
|
|
|
connect(keypad, SIGNAL(closing()), this, SLOT(keypadClosing()));
|
|
|
|
connect(keypad, SIGNAL(insertChar(const TQString &)), this, SLOT(insertChar(const TQString &)));
|
|
|
|
connect(keypad, SIGNAL(add()), this, SLOT(slotAdd()));
|
|
|
|
connect(keypad, SIGNAL(subtract()), this, SLOT(slotSubtract()));
|
|
|
|
connect(keypad, SIGNAL(multiply()), this, SLOT(slotMultiply()));
|
|
|
|
connect(keypad, SIGNAL(divide()), this, SLOT(slotDivide()));
|
|
|
|
connect(keypad, SIGNAL(enter()), this, SLOT(slotEnter()));
|
|
|
|
connect(keypad, SIGNAL(backspace()), this, SLOT(slotKeypadBackspace()));
|
|
|
|
connect(keypad, SIGNAL(eex()), this, SLOT(slotEEX()));
|
|
|
|
keypad->hide();
|
|
|
|
|
|
|
|
TQStringList options(i18n("Degrees"));
|
|
|
|
options.append(i18n("Radians"));
|
|
|
|
options.append(i18n("Grads"));
|
|
|
|
angGroup = new TDEListAction(i18n("Angle"), 0, 0, 0, actionCollection(), "angle");
|
|
|
|
angGroup->setItems(options);
|
|
|
|
|
|
|
|
options.clear();
|
|
|
|
options.append(i18n("Hexadecimal"));
|
|
|
|
options.append(i18n("Decimal"));
|
|
|
|
options.append(i18n("Octal"));
|
|
|
|
options.append(i18n("Binary"));
|
|
|
|
baseGroup = new TDEListAction(i18n("Base"), 0, 0, 0, actionCollection(), "base");
|
|
|
|
baseGroup->setItems(options);
|
|
|
|
|
|
|
|
TQStringList defaultFormulae;
|
|
|
|
formulae = new TDEListAction(i18n("&Formulae"), 0, 0, 0, actionCollection(), "formulae");
|
|
|
|
#include "formulae"
|
|
|
|
formulae->setItems(defaultFormulae);
|
|
|
|
formulae->setCurrentItem(-1);
|
|
|
|
|
|
|
|
(void) KStdAction::quit(this, SLOT(close()), actionCollection());
|
|
|
|
(void) KStdAction::open(this, SLOT(slotOpen()), actionCollection());
|
|
|
|
|
|
|
|
(void) KStdAction::preferences(this, SLOT(slotConfigure()), actionCollection());
|
|
|
|
(void) KStdAction::undo(this, SLOT(slotRestoreStack()), actionCollection())->setText(i18n("Restore stack levels"));
|
|
|
|
|
|
|
|
(void) KStdAction::configureToolbars(this, SLOT(configureToolBars()), actionCollection());
|
|
|
|
(void) KStdAction::keyBindings(this, SLOT(keyBindings()), actionCollection());
|
|
|
|
|
|
|
|
(void) new TDEAction(i18n("+/-"), "Alt+-", this, SLOT(slotNegative()), actionCollection(), "+/-");
|
|
|
|
(void) new TDEAction("x!", "Alt+!", this, SLOT(slotFactorial()), actionCollection(), "factorial");
|
|
|
|
(void) new TDEAction("1/x", "Alt+i", this, SLOT(slotInverse()), actionCollection(), "1/x");
|
|
|
|
(void) new TDEAction("10^x", 0, this, SLOT(slotRaiseTen()), actionCollection(), "10^x");
|
|
|
|
(void) new TDEAction("e^x", "Alt+E", this, SLOT(slotRaiseE()), actionCollection(), "e^x");
|
|
|
|
(void) new TDEAction("Mod", "Alt+M", this, SLOT(slotModulo()), actionCollection(), "modulo");
|
|
|
|
(void) new TDEAction("Ln", "Alt+L", this, SLOT(slotLn()), actionCollection(), "ln");
|
|
|
|
(void) new TDEAction("%", "Alt+%", this, SLOT(slotPercent()), actionCollection(), "percent");
|
|
|
|
(void) new TDEAction("Sqrt", "Alt+R", this, SLOT(slotSqrt()), actionCollection(), "sqrt");
|
|
|
|
(void) new TDEAction("x^2", "Alt+Shift+S", this, SLOT(slotSquared()), actionCollection(), "x^2");
|
|
|
|
(void) new TDEAction("y^x", "Alt+^", this, SLOT(slotPower()), actionCollection(), "y^x");
|
|
|
|
|
|
|
|
InvButton = new TDEToggleAction("Inv", "Ctrl+I", 0, 0, actionCollection(), "inverse");
|
|
|
|
HypButton = new TDEToggleAction("Hyp", "Ctrl+H", 0, 0, actionCollection(), "hyperbolic");
|
|
|
|
|
|
|
|
// bitwise
|
|
|
|
(void) new TDEAction(i18n("And"), "Alt+A", this, SLOT(slotAnd()), actionCollection(), "bitwise_and");
|
|
|
|
(void) new TDEAction(i18n("Or"), "Alt+O", this, SLOT(slotOr()), actionCollection(), "bitwise_or");
|
|
|
|
(void) new TDEAction(i18n("XOr"), "Alt+X", this, SLOT(slotXOr()), actionCollection(), "bitwise_xor");
|
|
|
|
(void) new TDEAction(i18n("Left Shift"), "back", 0, this, SLOT(slotLsh()), actionCollection(), "bitwise_lsh");
|
|
|
|
(void) new TDEAction(i18n("Right Shift"), "forward", 0, this, SLOT(slotRsh()), actionCollection(), "bitwise_rsh");
|
|
|
|
|
|
|
|
// trig
|
|
|
|
(void) new TDEAction("Sin", "Alt+S", this, SLOT(slotSine()), actionCollection(), "sin");
|
|
|
|
(void) new TDEAction("Cos", "Alt+C", this, SLOT(slotCosine()), actionCollection(), "cos");
|
|
|
|
(void) new TDEAction("Tan", "Alt+T", this, SLOT(slotTangent()), actionCollection(), "tan");
|
|
|
|
|
|
|
|
// edit
|
|
|
|
(void) new TDEAction(i18n("&Revert Stack Changes"), 0, this, SLOT(slotRevert()), actionCollection(), "revert");
|
|
|
|
(void) new TDEAction(i18n("&Drop"), 0, this, SLOT(slotDrop()), actionCollection(), "drop");
|
|
|
|
|
|
|
|
statusBar();
|
|
|
|
createGUI();
|
|
|
|
|
|
|
|
resize(430, 500);
|
|
|
|
applyMainWindowSettings(TDEGlobal::config(), "TopLevelWindow");
|
|
|
|
|
|
|
|
// signals and slots connections
|
|
|
|
connect(baseGroup, SIGNAL(activated(int)), this, SLOT(slotBaseChanged(int)));
|
|
|
|
connect(angGroup, SIGNAL(activated(int)), this, SLOT(slotAngleChanged(int)));
|
|
|
|
|
|
|
|
connect(formulae, SIGNAL(activated(const TQString &)), this, SLOT(runFormula(const TQString &)));
|
|
|
|
|
|
|
|
connect(HistoryBox->combo(), SIGNAL(activated(const TQString&)), this, SLOT(slotPushHighlighted(const TQString&)));
|
|
|
|
|
|
|
|
connect(LineEdit->edit(), SIGNAL(backspacePressed()), this, SLOT(slotBackspace()));
|
|
|
|
|
|
|
|
pi = asin(1L) * 2L;
|
|
|
|
variables["pi"] = pi;
|
|
|
|
defVariables.append("pi");
|
|
|
|
variables["e"] = exp(1);
|
|
|
|
defVariables.append("e");
|
|
|
|
variables["true"] = 1;
|
|
|
|
defVariables.append("true");
|
|
|
|
variables["false"] = 0;
|
|
|
|
defVariables.append("false");
|
|
|
|
variables["degkey"] = 0;
|
|
|
|
defVariables.append("degkey");
|
|
|
|
variables["radkey"] = 1;
|
|
|
|
defVariables.append("radkey");
|
|
|
|
variables["gradkey"] = 2;
|
|
|
|
defVariables.append("gradkey");
|
|
|
|
|
|
|
|
Stack = new TQValueList<double>;
|
|
|
|
SavedStack = new TQValueList<double>;
|
|
|
|
optionDialog = 0;
|
|
|
|
|
|
|
|
// how long do status msgs stay up? in ms
|
|
|
|
dispTime = 1500;
|
|
|
|
|
|
|
|
kapp->config()->setGroup("App");
|
|
|
|
|
|
|
|
bool showkeys = kapp->config()->readBoolEntry("show keypad", true);
|
|
|
|
toggleKeypad(showkeys);
|
|
|
|
keypadAct->setChecked(showkeys);
|
|
|
|
|
|
|
|
slotUpdateConfiguration();
|
|
|
|
|
|
|
|
kapp->config()->setGroup("Session");
|
|
|
|
|
|
|
|
TQStringList stackList = kapp->config()->readListEntry("Stack", ',');
|
|
|
|
int i;
|
|
|
|
|
|
|
|
TQStringList historyList = kapp->config()->readListEntry("History", ',');
|
|
|
|
int count = historyList.count();
|
|
|
|
if (historyList.first() != "Nothing" && count > 0)
|
|
|
|
{
|
|
|
|
if (count > histNum)
|
|
|
|
count = histNum;
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
HistoryBox->combo()->insertItem(*historyList.at(i));
|
|
|
|
|
|
|
|
HistoryBox->combo()->setCurrentItem(HistoryBox->combo()->count() - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
base = 10; // this necessary so we can
|
|
|
|
// setbase properly :P
|
|
|
|
|
|
|
|
// default config choices
|
|
|
|
runCommand("$degkey"); runCommand("setangle");
|
|
|
|
runCommand("10"); runCommand("setbase");
|
|
|
|
runCommand("$false"); runCommand("sethyp");
|
|
|
|
updateStack();
|
|
|
|
|
|
|
|
// load session file
|
|
|
|
openFile(TDEGlobal::dirs()->saveLocation("appdata") + "session");
|
|
|
|
|
|
|
|
saveStack();
|
|
|
|
|
|
|
|
LineEdit->edit()->setFocus();
|
|
|
|
|
|
|
|
statusBar()->message(i18n("Welcome to Mathemagics"), dispTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
Mathemagics::~Mathemagics()
|
|
|
|
{
|
|
|
|
delete Stack;
|
|
|
|
delete SavedStack;
|
|
|
|
delete optionDialog;
|
|
|
|
delete keypad;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::keypadClosing()
|
|
|
|
{
|
|
|
|
keypadAct->setChecked(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::insertChar(const TQString &s)
|
|
|
|
{
|
|
|
|
LineEdit->insert(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::updateStack()
|
|
|
|
{
|
|
|
|
StackLevel *level;
|
|
|
|
const int count = Stack->count();
|
|
|
|
int i = 1;
|
|
|
|
for (level = stackLevels.first(); level; level = stackLevels.next(), ++i)
|
|
|
|
{
|
|
|
|
if (i > count)
|
|
|
|
{
|
|
|
|
for (; level; level = stackLevels.next())
|
|
|
|
{
|
|
|
|
level->edit()->clear();
|
|
|
|
level->setEnabled(false);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
level->setEnabled(true);
|
|
|
|
level->edit()->setText(format(*Stack->at(i - 1)));
|
|
|
|
}
|
|
|
|
|
|
|
|
TQTimer::singleShot(100, this, SLOT(scrollToBottom()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::enter()
|
|
|
|
{
|
|
|
|
const bool notDec = base != 10;
|
|
|
|
bool noClear = false;
|
|
|
|
|
|
|
|
saveStack();
|
|
|
|
|
|
|
|
bool oldNoSave = noSave;
|
|
|
|
noSave = true;
|
|
|
|
|
|
|
|
TQStringList entryNums = this->entryNums;
|
|
|
|
this->entryNums.clear();
|
|
|
|
|
|
|
|
TQString oldLineText = LineEdit->edit()->text();
|
|
|
|
LineEdit->clear();
|
|
|
|
|
|
|
|
for (TQStringList::Iterator it = entryNums.begin(); it != entryNums.end(); ++it)
|
|
|
|
{
|
|
|
|
int eIndex;
|
|
|
|
int eqIndex = (*it).find('=');
|
|
|
|
int dolIndex = (*it).find('$');
|
|
|
|
bool ok;
|
|
|
|
double val;
|
|
|
|
|
|
|
|
if (eqIndex >= 0 && (dolIndex < 0 || dolIndex > eqIndex)) // add equation
|
|
|
|
{
|
|
|
|
TQString formulaName = (*it).left(eqIndex);
|
|
|
|
if (formulaName.isEmpty())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
TQString formula = (*it).right((*it).length() - eqIndex - 1);
|
|
|
|
|
|
|
|
for (++it; it != entryNums.end(); ++it)
|
|
|
|
{
|
|
|
|
formula.append(" ");
|
|
|
|
formula.append(*it);
|
|
|
|
}
|
|
|
|
|
|
|
|
formulas[formulaName] = formula;
|
|
|
|
|
|
|
|
TQStringList newList(formulae->items());
|
|
|
|
newList.remove(formulaName);
|
|
|
|
|
|
|
|
if (!formulaName.isEmpty())
|
|
|
|
newList.append(formulaName);
|
|
|
|
|
|
|
|
formulae->setItems(newList);
|
|
|
|
|
|
|
|
statusBar()->message(i18n("Formula %1 added").arg(formulaName), dispTime);
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if ((eIndex = (*it).find('E')) != -1 && !notDec) // E found
|
|
|
|
{
|
|
|
|
TQString firstArg = (*it).left(eIndex);
|
|
|
|
if (firstArg.isEmpty())
|
|
|
|
continue;
|
|
|
|
TQString secondArg = (*it).right((*it).length() - eIndex - 1);
|
|
|
|
val = firstArg.toDouble(&ok) * pow(10, secondArg.toDouble(&ok));
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
Stack->prepend(val);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// else try something else below
|
|
|
|
}
|
|
|
|
|
|
|
|
// plain
|
|
|
|
val = format(*it, &ok);
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
Stack->prepend(val);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (enterMode)
|
|
|
|
if (!runCommand((*it).lower()))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (noClear)
|
|
|
|
LineEdit->edit()->setText(oldLineText);
|
|
|
|
|
|
|
|
noSave = oldNoSave;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotEnter()
|
|
|
|
{
|
|
|
|
enterMode = true;
|
|
|
|
|
|
|
|
if (LineEdit->text().isEmpty() && Stack->count() >= 1)
|
|
|
|
// dup
|
|
|
|
Stack->prepend(Stack->first());
|
|
|
|
else
|
|
|
|
parseArgs(false, true, false);
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
|
|
|
|
enterMode = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Mathemagics::parseArgs(unsigned int reqArgs, bool autoEnter, bool save)
|
|
|
|
{
|
|
|
|
int entryNumsCount = 0;
|
|
|
|
|
|
|
|
if (!LineEdit->text().isEmpty())
|
|
|
|
{
|
|
|
|
entryNums = TQStringList::split(TQChar(' '), LineEdit->text());
|
|
|
|
entryNumsCount = entryNums.count();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Stack->count() + entryNumsCount < reqArgs)
|
|
|
|
{
|
|
|
|
changeStatusError(i18n("At least %1 arguments required").arg(reqArgs));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (save)
|
|
|
|
saveStack();
|
|
|
|
|
|
|
|
if (autoEnter)
|
|
|
|
enter();
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Mathemagics::testArgs()
|
|
|
|
{
|
|
|
|
int entryNumsCount = 0;
|
|
|
|
|
|
|
|
if (!LineEdit->text().isEmpty())
|
|
|
|
{
|
|
|
|
entryNums = TQStringList::split(TQChar(' '), LineEdit->text());
|
|
|
|
entryNumsCount = entryNums.count();
|
|
|
|
}
|
|
|
|
|
|
|
|
return entryNumsCount;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::saveStack()
|
|
|
|
{
|
|
|
|
if (noSave)
|
|
|
|
return;
|
|
|
|
|
|
|
|
*SavedStack = *Stack;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotRestoreStack()
|
|
|
|
{
|
|
|
|
// a simple swap
|
|
|
|
TQValueList<double> *SavedStackPtr = Stack;
|
|
|
|
Stack = SavedStack;
|
|
|
|
SavedStack = SavedStackPtr;
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotAdd()
|
|
|
|
{
|
|
|
|
if (!parseArgs(2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double theResult = (* Stack->at(0)) + (* Stack->at(1));
|
|
|
|
changeStatus(& theResult, '+');
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotSubtract()
|
|
|
|
{
|
|
|
|
if (!parseArgs(2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double theResult = (* Stack->at(1)) - (* Stack->at(0));
|
|
|
|
changeStatus(& theResult, '-');
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotMultiply()
|
|
|
|
{
|
|
|
|
if (!parseArgs(2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double theResult = (* Stack->at(0)) * (* Stack->at(1));
|
|
|
|
changeStatus(& theResult, '*');
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotDivide()
|
|
|
|
{
|
|
|
|
getArgs(1);
|
|
|
|
if (args.first() == 0)
|
|
|
|
{
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!parseArgs(2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double theResult = (* Stack->at(1)) / (* Stack->at(0));
|
|
|
|
changeStatus(& theResult, '/');
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotRaiseE()
|
|
|
|
{
|
|
|
|
if (!parseArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double theResult;
|
|
|
|
|
|
|
|
theResult = exp(Stack->first());
|
|
|
|
changeStatus(& theResult, i18n("e ^ "), 1);
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotInverse()
|
|
|
|
{
|
|
|
|
if (!parseArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double theResult;
|
|
|
|
|
|
|
|
theResult = 1 / Stack->first();
|
|
|
|
changeStatus(& theResult, i18n("1 / "), 1);
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotSquared()
|
|
|
|
{
|
|
|
|
if (!parseArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double level1 = Stack->first();
|
|
|
|
level1 *= level1;
|
|
|
|
changeStatus(&level1, i18n(" ^ 2"));
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(level1);
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotSqrt()
|
|
|
|
{
|
|
|
|
getArgs(1);
|
|
|
|
if (args.first() < 0)
|
|
|
|
{
|
|
|
|
changeStatusError(i18n("Complex number"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!parseArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double theResult = sqrt(Stack->first());
|
|
|
|
changeStatus(&theResult, i18n("Square root of "), 1);
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotSine()
|
|
|
|
{
|
|
|
|
double theResult;
|
|
|
|
|
|
|
|
if (InvButton->isChecked())
|
|
|
|
{
|
|
|
|
if (HypButton->isChecked())
|
|
|
|
{
|
|
|
|
if (!parseArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
theResult = asinh(Stack->first());
|
|
|
|
changeStatus(& theResult, i18n("Hyp ArcSine of "), 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!getArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double lev1 = args.first();
|
|
|
|
if (lev1 < -1 || lev1 > 1)
|
|
|
|
{
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
parseArgs(1);
|
|
|
|
|
|
|
|
theResult = angOut(asin(Stack->first()));
|
|
|
|
changeStatus(& theResult, i18n("ArcSine of "), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
InvButton->setChecked(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!parseArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (HypButton->isChecked())
|
|
|
|
{
|
|
|
|
theResult = sinh(Stack->first());
|
|
|
|
changeStatus(& theResult, i18n("Hyp Sine of "), 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
theResult = sin(angConv(Stack->first()));
|
|
|
|
changeStatus(& theResult, i18n("Sine of "), 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotCosine()
|
|
|
|
{
|
|
|
|
double theResult;
|
|
|
|
|
|
|
|
if (InvButton->isChecked())
|
|
|
|
{
|
|
|
|
if (!getArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (HypButton->isChecked())
|
|
|
|
{
|
|
|
|
if (args.first() < 1)
|
|
|
|
{
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
parseArgs(1);
|
|
|
|
|
|
|
|
theResult = acosh(Stack->first());
|
|
|
|
changeStatus(& theResult, i18n("Hyp ArcCosine of "), 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double lev1 = args.first();
|
|
|
|
if (lev1 < -1 || lev1 > 1)
|
|
|
|
{
|
|
|
|
error();
|
|
|
|
InvButton->setChecked(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
parseArgs(1);
|
|
|
|
|
|
|
|
theResult = angOut(acos(Stack->first()));
|
|
|
|
changeStatus(& theResult, i18n("ArcCosine of "), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
InvButton->setChecked(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!parseArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (HypButton->isChecked())
|
|
|
|
{
|
|
|
|
theResult = cosh(Stack->first());
|
|
|
|
changeStatus(& theResult, i18n("Hyp Cosine of "), 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
theResult = cos(angConv(Stack->first()));
|
|
|
|
changeStatus(& theResult, i18n("Cosine of "), 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotTangent()
|
|
|
|
{
|
|
|
|
double theResult;
|
|
|
|
|
|
|
|
if (InvButton->isChecked())
|
|
|
|
{
|
|
|
|
if (HypButton->isChecked())
|
|
|
|
{
|
|
|
|
if (!getArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (fabs(args.first()) > 1)
|
|
|
|
{
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
parseArgs(1);
|
|
|
|
|
|
|
|
theResult = atanh(Stack->first());
|
|
|
|
changeStatus(& theResult, i18n("Hyp ArcTangent of "), 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!parseArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
theResult = angOut(atan(Stack->first()));
|
|
|
|
changeStatus(& theResult, i18n("ArcTangent of "), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
InvButton->setChecked(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!parseArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (HypButton->isChecked())
|
|
|
|
{
|
|
|
|
theResult = tanh(Stack->first());
|
|
|
|
changeStatus(& theResult, i18n("Hyp Tangent of "), 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
theResult = tan(angConv(Stack->first()));
|
|
|
|
changeStatus(& theResult, i18n("Tangent of "), 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotLn()
|
|
|
|
{
|
|
|
|
if (!getArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (args.first() <= 0)
|
|
|
|
{
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
double theResult;
|
|
|
|
parseArgs(1);
|
|
|
|
|
|
|
|
theResult = log(Stack->first());
|
|
|
|
changeStatus(& theResult, i18n("ln "), 1);
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotFactorial()
|
|
|
|
{
|
|
|
|
if (!getArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double lev1 = args.first();
|
|
|
|
|
|
|
|
if ((int)lev1 != lev1 || lev1 <= 0)
|
|
|
|
{
|
|
|
|
changeStatusError(i18n("Not implemented"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (parseArgs(1))
|
|
|
|
{
|
|
|
|
int n = fact(Stack->first());
|
|
|
|
double theDouble = (double)n;
|
|
|
|
changeStatus(& theDouble, "!");
|
|
|
|
Stack->first() = n;
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int Mathemagics::fact(int n)
|
|
|
|
{
|
|
|
|
if (n <= 0)
|
|
|
|
return 1;
|
|
|
|
else
|
|
|
|
return n * fact(n-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotRaiseTen()
|
|
|
|
{
|
|
|
|
if (!parseArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double theResult = pow(10, Stack->first());
|
|
|
|
|
|
|
|
changeStatus(&theResult, i18n("10 ^ "), 1);
|
|
|
|
|
|
|
|
Stack->first() = theResult;
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotEEX()
|
|
|
|
{
|
|
|
|
if (base == 10 || base >= 15)
|
|
|
|
LineEdit->insert(TQString("E"));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotPercent()
|
|
|
|
{
|
|
|
|
double theResult;
|
|
|
|
|
|
|
|
if (!parseArgs(2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
theResult = (*Stack->at(1) / Stack->first()) * 100;
|
|
|
|
changeStatus(&theResult, '%');
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->first() = theResult;
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotModulo()
|
|
|
|
{
|
|
|
|
double theResult;
|
|
|
|
|
|
|
|
if (!getArgs(1))
|
|
|
|
return;
|
|
|
|
if (args.first() == 0)
|
|
|
|
{
|
|
|
|
error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!parseArgs(2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
theResult = fmod(*Stack->at(1), Stack->first());
|
|
|
|
changeStatus(&theResult, TQString(i18n("%1 mod ")).arg(*Stack->at(1)), 1);
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->first() = theResult;
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotPower()
|
|
|
|
{
|
|
|
|
double theResult;
|
|
|
|
|
|
|
|
if (!getArgs(2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (InvButton->isChecked())
|
|
|
|
{
|
|
|
|
if (*args.at(1) < 0)
|
|
|
|
{
|
|
|
|
changeStatusError(i18n("Complex number"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
parseArgs(2);
|
|
|
|
|
|
|
|
theResult = pow(*Stack->at(1), 1 / Stack->first());
|
|
|
|
changeStatus(&theResult, TQString(i18n("%1 root of ")).arg(format(*Stack->at(1))), true);
|
|
|
|
|
|
|
|
InvButton->setChecked(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
double lev1 = args.first();
|
|
|
|
|
|
|
|
if (*args.at(1) < 0 && (int)lev1 != lev1)
|
|
|
|
{
|
|
|
|
changeStatusError(i18n("Complex number"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
parseArgs(2);
|
|
|
|
|
|
|
|
theResult = pow(*Stack->at(1), Stack->first());
|
|
|
|
changeStatus(&theResult, TQString(i18n("%1 ^ ")).arg(format(*Stack->at(1))), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->first() = theResult;
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotNegative()
|
|
|
|
{
|
|
|
|
if (LineEdit->text().isEmpty() && Stack->count() >= 1)
|
|
|
|
{
|
|
|
|
saveStack();
|
|
|
|
Stack->first() *= -1;
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
TQString text = LineEdit->text();
|
|
|
|
|
|
|
|
unsigned int cursPos = LineEdit->edit()->cursorPosition();
|
|
|
|
unsigned int length = text.length();
|
|
|
|
|
|
|
|
int eindex = text.findRev('E', cursPos - length - 1);
|
|
|
|
int negIndex = text.findRev(' ', cursPos - length - 1) + 1;
|
|
|
|
|
|
|
|
if (base == 10 && eindex != -1)
|
|
|
|
negIndex = eindex + 1;
|
|
|
|
|
|
|
|
if (text.at(negIndex) == TQChar('-'))
|
|
|
|
{
|
|
|
|
text.remove(negIndex, 1);
|
|
|
|
LineEdit->edit()->setText(text);
|
|
|
|
LineEdit->edit()->setCursorPosition(cursPos - 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
text.insert(negIndex, '-');
|
|
|
|
LineEdit->edit()->setText(text);
|
|
|
|
LineEdit->edit()->setCursorPosition(cursPos + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotAnd()
|
|
|
|
{
|
|
|
|
long double theResult;
|
|
|
|
if (parseArgs(2))
|
|
|
|
{
|
|
|
|
theResult = (long int)Stack->first() & (long int)*Stack->at(1);
|
|
|
|
double pass = (double)theResult;
|
|
|
|
changeStatus(&pass, TQString(i18n("%1 AND ")).arg(format(*Stack->at(1))), 1);
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotXOr()
|
|
|
|
{
|
|
|
|
if (!parseArgs(2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double theResult;
|
|
|
|
theResult = (long int)Stack->first() ^ (long int)*Stack->at(1);
|
|
|
|
changeStatus(&theResult, TQString(i18n("%1 XOR ")).arg(format(*Stack->at(1))), 1);
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotOr()
|
|
|
|
{
|
|
|
|
if (!parseArgs(2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double theResult;
|
|
|
|
theResult = (long int)Stack->first() | (long int)*Stack->at(1);
|
|
|
|
changeStatus(&theResult, TQString(i18n("%1 OR ")).arg(format(*Stack->at(1))), 1);
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotRsh()
|
|
|
|
{
|
|
|
|
if (!parseArgs(2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double theResult;
|
|
|
|
|
|
|
|
theResult = (long int)*Stack->at(1) >> (long int)Stack->first();
|
|
|
|
changeStatus(&theResult, TQString(i18n("%1 RSH ")).arg(format(*Stack->at(1))), true);
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotLsh()
|
|
|
|
{
|
|
|
|
if (!parseArgs(2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
double theResult;
|
|
|
|
|
|
|
|
theResult = (long int)*Stack->at(1) << (long int)Stack->first();
|
|
|
|
changeStatus(&theResult, TQString(i18n("%1 LSH ")).arg(format(*Stack->at(1))), true);
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->pop_front();
|
|
|
|
Stack->prepend(theResult);
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotDup2()
|
|
|
|
{
|
|
|
|
if (!parseArgs(2))
|
|
|
|
return;
|
|
|
|
|
|
|
|
Stack->prepend(* Stack->at(1));
|
|
|
|
Stack->prepend(* Stack->at(1));
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotDrop()
|
|
|
|
{
|
|
|
|
if (!parseArgs(1))
|
|
|
|
return;
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotKeypadBackspace()
|
|
|
|
{
|
|
|
|
slotBackspace();
|
|
|
|
LineEdit->edit()->backspace();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotBackspace()
|
|
|
|
{
|
|
|
|
if (InvButton->isChecked())
|
|
|
|
{
|
|
|
|
saveStack();
|
|
|
|
|
|
|
|
Stack->clear();
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
InvButton->setChecked(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (LineEdit->text().isEmpty())
|
|
|
|
{
|
|
|
|
if (!Stack->isEmpty() && delDrops)
|
|
|
|
{
|
|
|
|
saveStack();
|
|
|
|
Stack->pop_front();
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::closeEvent(TQCloseEvent * /*e*/)
|
|
|
|
{
|
|
|
|
TQString list;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
kapp->config()->setGroup("Session");
|
|
|
|
|
|
|
|
// save history for next time
|
|
|
|
int count = HistoryBox->combo()->count();
|
|
|
|
|
|
|
|
if (count != 0)
|
|
|
|
{
|
|
|
|
list = HistoryBox->combo()->text(0);
|
|
|
|
for (i = 1; i < (unsigned int)count; i++)
|
|
|
|
{
|
|
|
|
list.append(',');
|
|
|
|
list.append(HistoryBox->combo()->text(i));
|
|
|
|
}
|
|
|
|
kapp->config()->writeEntry("History", list);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
kapp->config()->writeEntry("History", "Nothing");
|
|
|
|
|
|
|
|
|
|
|
|
kapp->config()->setGroup("App");
|
|
|
|
kapp->config()->writeEntry("show keypad", keypadAct->isChecked());
|
|
|
|
|
|
|
|
kapp->config()->sync();
|
|
|
|
|
|
|
|
saveFile(TDEGlobal::dirs()->saveLocation("appdata") + "session");
|
|
|
|
|
|
|
|
saveMainWindowSettings(TDEGlobal::config(), "TopLevelWindow");
|
|
|
|
|
|
|
|
kapp->quit();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotConfigure()
|
|
|
|
{
|
|
|
|
if (optionDialog == 0)
|
|
|
|
{
|
|
|
|
optionDialog = new ConfigureDialog(topLevelWidget());
|
|
|
|
|
|
|
|
if (optionDialog == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
connect(optionDialog, SIGNAL(hidden()),this,SLOT(slotConfigureHide()));
|
|
|
|
connect(optionDialog, SIGNAL(valueChanged()), this, SLOT(slotUpdateConfiguration()));
|
|
|
|
connect(optionDialog, SIGNAL(clearHistory()), this, SLOT(clearHistory()));
|
|
|
|
}
|
|
|
|
|
|
|
|
optionDialog->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotConfigureHide()
|
|
|
|
{
|
|
|
|
TQTimer::singleShot(0, this, SLOT(slotConfigureDestroy()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotConfigureDestroy()
|
|
|
|
{
|
|
|
|
if (optionDialog != 0 && optionDialog->isVisible() == 0)
|
|
|
|
{
|
|
|
|
delete optionDialog;
|
|
|
|
optionDialog = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotBaseChanged(int id)
|
|
|
|
{
|
|
|
|
switch (id)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
base = 16;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
base = 10;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
base = 8;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 3:
|
|
|
|
base = 2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
|
|
|
|
statusBar()->message(i18n("Base changed to %1").arg(base), dispTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotAngleChanged(int id)
|
|
|
|
{
|
|
|
|
angle = id;
|
|
|
|
|
|
|
|
statusBar()->message(i18n("Angle changed to %1").arg(theAngle()), dispTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::recreateStackLevels()
|
|
|
|
{
|
|
|
|
stackLevels.clear();
|
|
|
|
|
|
|
|
for (int i = numStackLevels; i > 0; --i)
|
|
|
|
{
|
|
|
|
StackLevel *level = new StackLevel(i, boxParent);
|
|
|
|
connect(level, SIGNAL(buttonPressed(int)), this, SLOT(slotRoll(int)));
|
|
|
|
connect(level, SIGNAL(returnPressed(int)), this, SLOT(slotUpdateStackLevel(int)));
|
|
|
|
|
|
|
|
bigBox->addWidget(level);
|
|
|
|
stackLevels.prepend(level);
|
|
|
|
level->show();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::scrollToBottom()
|
|
|
|
{
|
|
|
|
topLevel->ensureVisible(1, boxParent->height() - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotUpdateConfiguration()
|
|
|
|
{
|
|
|
|
kapp->config()->setGroup("App");
|
|
|
|
|
|
|
|
int oldNum = numStackLevels;
|
|
|
|
numStackLevels = kapp->config()->readNumEntry("numStackLevels", 12);
|
|
|
|
if (oldNum != numStackLevels)
|
|
|
|
recreateStackLevels();
|
|
|
|
|
|
|
|
fixedPrec = kapp->config()->readBoolEntry("fixedPrec", false);
|
|
|
|
toSaveStack = kapp->config()->readBoolEntry("saveStack", true);
|
|
|
|
showPeriod = kapp->config()->readBoolEntry("showPeriod", false);
|
|
|
|
formatPrec = kapp->config()->readNumEntry("formatPrec", 8);
|
|
|
|
histNum = kapp->config()->readNumEntry("histNum", 15);
|
|
|
|
delDrops = kapp->config()->readBoolEntry("delDrops", true);
|
|
|
|
histDetail = kapp->config()->readBoolEntry("histDetail", false);
|
|
|
|
beep = kapp->config()->readBoolEntry("beep", true);
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
|
|
|
|
while (histNum < HistoryBox->combo()->count())
|
|
|
|
HistoryBox->combo()->removeItem(0);
|
|
|
|
|
|
|
|
HistoryBox->combo()->setCurrentItem(HistoryBox->combo()->count() - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotUpdateStackLevel(int level)
|
|
|
|
{
|
|
|
|
saveStack();
|
|
|
|
|
|
|
|
const TQString stackText(stackLevels.at(level - 1)->edit()->text());
|
|
|
|
if (stackText.isEmpty())
|
|
|
|
{
|
|
|
|
Stack->remove(Stack->at(level - 1));
|
|
|
|
updateStack();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ok;
|
|
|
|
double val = format(stackText.section(' ', 0, 0), &ok);
|
|
|
|
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
(*Stack->at(level - 1)) = val;
|
|
|
|
stackLevels.at(level - 1)->edit()->setText(format(val));
|
|
|
|
statusBar()->message(i18n("Change to level %1 applied").arg(level), dispTime);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
changeStatusError(i18n("Bad number"));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotRevert()
|
|
|
|
{
|
|
|
|
updateStack();
|
|
|
|
statusBar()->message(i18n("Changes destroyed"), dispTime);
|
|
|
|
}
|
|
|
|
|
|
|
|
double Mathemagics::format(TQString theString, bool *ok)
|
|
|
|
{
|
|
|
|
return (base != 10 ? (double)theString.toInt(ok, base) : theString.toDouble(ok));
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Mathemagics::format(double theDouble)
|
|
|
|
{
|
|
|
|
if (base != 10)
|
|
|
|
{
|
|
|
|
TQString convStr;
|
|
|
|
convStr.setNum((int)theDouble, base);
|
|
|
|
if (showPeriod)
|
|
|
|
convStr.append('.');
|
|
|
|
return convStr;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString decimal = TQString::number(theDouble, 'f', formatPrec);
|
|
|
|
|
|
|
|
// leave zeroes on
|
|
|
|
if (fixedPrec)
|
|
|
|
return decimal;
|
|
|
|
|
|
|
|
//this algorithm will find the last non-zero digits's index
|
|
|
|
int i;
|
|
|
|
for (i = decimal.length() - 1; i >= 0; i--)
|
|
|
|
{
|
|
|
|
if (decimal.at(i) != '0')
|
|
|
|
{
|
|
|
|
if (decimal.at(i) == '.')
|
|
|
|
{
|
|
|
|
if (!showPeriod) // get rid of the period
|
|
|
|
i--;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// return the stuff that has no zeroes
|
|
|
|
return decimal.mid(0, i + 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
double Mathemagics::angConv(const double theDouble)
|
|
|
|
{
|
|
|
|
switch (angle)
|
|
|
|
{
|
|
|
|
case 0: // deg2rad
|
|
|
|
return (((2L*pi)/360L) * theDouble);
|
|
|
|
|
|
|
|
case 1: // rad2rad
|
|
|
|
return (theDouble);
|
|
|
|
|
|
|
|
case 2: // grad2rad
|
|
|
|
return ((pi/200L) * theDouble);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (theDouble);
|
|
|
|
}
|
|
|
|
|
|
|
|
double Mathemagics::angOut(const double theDouble)
|
|
|
|
{
|
|
|
|
switch (angle)
|
|
|
|
{
|
|
|
|
case 0: // rad2deg
|
|
|
|
return ((360L/(2L*pi)) * theDouble);
|
|
|
|
|
|
|
|
case 1: // rad2rad
|
|
|
|
return (theDouble);
|
|
|
|
|
|
|
|
case 2: // rad2grad
|
|
|
|
return ((200L/pi) * theDouble);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (theDouble);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Mathemagics::getArgs(unsigned int num)
|
|
|
|
{
|
|
|
|
args.clear();
|
|
|
|
unsigned int i;
|
|
|
|
unsigned int lineArgs = testArgs();
|
|
|
|
unsigned int stackArgs = Stack->count();
|
|
|
|
if (lineArgs + stackArgs < num)
|
|
|
|
{
|
|
|
|
changeStatusError(i18n("Too few arguments"));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = lineArgs; i > 0; i--)
|
|
|
|
{
|
|
|
|
args.prepend(format(*entryNums.at(i - 1)));
|
|
|
|
if (args.count() == num) return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < (num - lineArgs); i++)
|
|
|
|
{
|
|
|
|
args.prepend(*Stack->at(i));
|
|
|
|
if (args.count() == num) return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false; // won't get here
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotRoll(int level)
|
|
|
|
{
|
|
|
|
saveStack();
|
|
|
|
|
|
|
|
if (level <= 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (InvButton->isChecked())
|
|
|
|
{
|
|
|
|
rolld(level);
|
|
|
|
InvButton->setChecked(false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
roll(level);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::roll(unsigned int index)
|
|
|
|
{
|
|
|
|
if (Stack->count() < index || index <= 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Stack->prepend(* Stack->at(index - 1));
|
|
|
|
Stack->remove(Stack->at(index));
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::rolld(unsigned int index)
|
|
|
|
{
|
|
|
|
if (Stack->count() < index || index <= 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Stack->insert(Stack->at(index), Stack->first());
|
|
|
|
Stack->pop_front();
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::changeStatus(TQString text)
|
|
|
|
{
|
|
|
|
const unsigned int maxLength = 30;
|
|
|
|
|
|
|
|
// keep hisNnum history spots, should never go over histNum
|
|
|
|
// this removes last item..
|
|
|
|
if (HistoryBox->combo()->count() >= histNum) HistoryBox->combo()->removeItem(0);
|
|
|
|
|
|
|
|
if (histDetail)
|
|
|
|
text = TQString(text + i18n("Base: %2; %3")).arg(base).arg(theAngle());
|
|
|
|
|
|
|
|
if (text.length() > maxLength)
|
|
|
|
{
|
|
|
|
text = text.right(maxLength - 4);
|
|
|
|
text.prepend("... ");
|
|
|
|
}
|
|
|
|
|
|
|
|
HistoryBox->combo()->insertItem(text, -1);
|
|
|
|
HistoryBox->combo()->setCurrentItem(HistoryBox->combo()->count() - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::clearHistory()
|
|
|
|
{
|
|
|
|
HistoryBox->combo()->clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString Mathemagics::theAngle()
|
|
|
|
{
|
|
|
|
switch (angle)
|
|
|
|
{
|
|
|
|
case (0):
|
|
|
|
return "Deg";
|
|
|
|
|
|
|
|
case (1):
|
|
|
|
return "Rad";
|
|
|
|
|
|
|
|
case (2):
|
|
|
|
return "Grad";
|
|
|
|
}
|
|
|
|
|
|
|
|
return "Deg";
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotPushHighlighted(const TQString& text)
|
|
|
|
{
|
|
|
|
saveStack();
|
|
|
|
|
|
|
|
int pipeIndex = text.findRev('|') - 1;
|
|
|
|
int spaceIndex = text.findRev(' ', pipeIndex);
|
|
|
|
|
|
|
|
if (pipeIndex == -2) // no pipe
|
|
|
|
{
|
|
|
|
Stack->prepend(format(text.mid(spaceIndex, text.length() - spaceIndex)));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int precSpaceIndex = text.findRev(' ', spaceIndex - 1);
|
|
|
|
Stack->prepend(format(text.mid(precSpaceIndex, spaceIndex - precSpaceIndex)));
|
|
|
|
}
|
|
|
|
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::error()
|
|
|
|
{
|
|
|
|
changeStatusError("Bad arguments");
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::changeStatusError(TQString text)
|
|
|
|
{
|
|
|
|
text.prepend(i18n("Error: "));
|
|
|
|
statusBar()->message(text, dispTime);
|
|
|
|
|
|
|
|
if (beep)
|
|
|
|
KNotifyClient::beep("Generic Error");
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::changeStatus(double * res, char op)
|
|
|
|
{
|
|
|
|
changeStatus(TQString(i18n("%1 %2 %3 = %4")).arg(format(*Stack->at(1))).arg(op).arg(format(Stack->first())).arg(format(*res)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::changeStatus(double * res, TQString op, bool prepend)
|
|
|
|
{
|
|
|
|
if (prepend)
|
|
|
|
changeStatus(TQString(i18n("%1%2 = %3")).arg(op).arg(format(Stack->first())).arg(format(*res)));
|
|
|
|
else
|
|
|
|
changeStatus(TQString(i18n("%1%2 = %3")).arg(format(Stack->first())).arg(op).arg(format(*res)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::toggleKeypad(bool on)
|
|
|
|
{
|
|
|
|
if (on)
|
|
|
|
keypad->show();
|
|
|
|
else
|
|
|
|
keypad->hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::slotOpen()
|
|
|
|
{
|
|
|
|
TQString filename = KFileDialog::getOpenFileName();
|
|
|
|
if (filename.isNull())
|
|
|
|
return;
|
|
|
|
|
|
|
|
openFile(filename);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::openFile(const TQString &filename)
|
|
|
|
{
|
|
|
|
TQFile f(filename);
|
|
|
|
if (!f.open(IO_ReadOnly))
|
|
|
|
return;
|
|
|
|
|
|
|
|
enterMode = true;
|
|
|
|
|
|
|
|
TQTextStream t(&f);
|
|
|
|
while (!t.eof())
|
|
|
|
{
|
|
|
|
TQString s = t.readLine();
|
|
|
|
|
|
|
|
// comments
|
|
|
|
if (s.at(0) == '#')
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (!s.isEmpty())
|
|
|
|
{
|
|
|
|
entryNums = TQStringList::split(TQChar(' '), s);
|
|
|
|
enter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
enterMode = false;
|
|
|
|
updateStack();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::saveFile(const TQString &filename)
|
|
|
|
{
|
|
|
|
TQFile f(filename);
|
|
|
|
if (!f.open(IO_WriteOnly))
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQTextStream t(&f);
|
|
|
|
|
|
|
|
t << "# Saved by mathemagics" << endl;
|
|
|
|
|
|
|
|
t.precision(15);
|
|
|
|
|
|
|
|
if (toSaveStack)
|
|
|
|
{
|
|
|
|
// this is the reverse
|
|
|
|
|
|
|
|
t << "# stack" << endl;
|
|
|
|
|
|
|
|
bool already = false;
|
|
|
|
|
|
|
|
TQValueList<double>::Iterator it = Stack->end();
|
|
|
|
it--;
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
{
|
|
|
|
if (already)
|
|
|
|
t << " ";
|
|
|
|
t << *it;
|
|
|
|
|
|
|
|
already = true;
|
|
|
|
|
|
|
|
if (it == Stack->begin())
|
|
|
|
break;
|
|
|
|
else
|
|
|
|
it--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
t << endl;
|
|
|
|
|
|
|
|
t << "# functions" << endl;
|
|
|
|
for (TQMap<TQString, TQString>::Iterator it = formulas.begin(); it != formulas.end(); ++it)
|
|
|
|
{
|
|
|
|
if (defFormulas.contains(it.key()) <= 0)
|
|
|
|
t << it.key() << "=" << it.data() << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
t << "# variables" << endl;
|
|
|
|
for (TQMap<TQString, double>::Iterator it = variables.begin(); it != variables.end(); ++it)
|
|
|
|
{
|
|
|
|
if (defVariables.contains(it.key()) <= 0)
|
|
|
|
t << it.data() << " $" << it.key() << "=" << endl;;
|
|
|
|
}
|
|
|
|
|
|
|
|
t << "# settings" << endl;
|
|
|
|
t << base << " setbase" << endl;
|
|
|
|
t << (angle == 0? "$degkey" : angle == 1? "$radkey" : "$gradkey") << " setangle" << endl;
|
|
|
|
t << (HypButton->isChecked() ? "$true" : "$false") << " sethyp" << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::runFormula(const TQString &name)
|
|
|
|
{
|
|
|
|
formulae->setCurrentItem(-1);
|
|
|
|
TQString s = formulas[name];
|
|
|
|
|
|
|
|
saveStack();
|
|
|
|
|
|
|
|
bool oldNoSave = noSave;
|
|
|
|
noSave = true;
|
|
|
|
|
|
|
|
TQStringList l = TQStringList::split(' ', s);
|
|
|
|
for (TQStringList::Iterator it = l.begin(); it != l.end(); ++it)
|
|
|
|
{
|
|
|
|
TQString command = (*it);
|
|
|
|
bool ok;
|
|
|
|
double num = format(command, &ok);
|
|
|
|
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
Stack->prepend(num);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!runCommand(command))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
noSave = oldNoSave;
|
|
|
|
}
|
|
|
|
|
|
|
|
// tests and returns startswith, and removes the search string from string if matches
|
|
|
|
bool removeStartsWith(TQString &s, const TQString &search)
|
|
|
|
{
|
|
|
|
if (s.startsWith(search))
|
|
|
|
{
|
|
|
|
s = s.right(s.length() - search.length());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Mathemagics::runCommand(const TQString &command)
|
|
|
|
{
|
|
|
|
// case insensitive
|
|
|
|
TQString operateOn = command.lower();
|
|
|
|
|
|
|
|
// allows operators to be embedded in numbers
|
|
|
|
// this finds a number at beginning of command
|
|
|
|
|
|
|
|
while (!operateOn.isEmpty())
|
|
|
|
{
|
|
|
|
TQChar firstChar(operateOn.at(0));
|
|
|
|
if (firstChar.isNumber())
|
|
|
|
{
|
|
|
|
for (int i = operateOn.length(); i > 0; --i)
|
|
|
|
{
|
|
|
|
bool ok;
|
|
|
|
double num = format(operateOn.left(i), &ok);
|
|
|
|
|
|
|
|
if (ok)
|
|
|
|
{
|
|
|
|
Stack->prepend(num);
|
|
|
|
operateOn = operateOn.right(operateOn.length() - i);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (firstChar == '$')
|
|
|
|
{
|
|
|
|
TQString varName = operateOn.right(operateOn.length() - 1);
|
|
|
|
if (varName.isEmpty())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
int eqIndex = varName.find('=');
|
|
|
|
|
|
|
|
if (eqIndex >= 0)
|
|
|
|
{
|
|
|
|
// assign
|
|
|
|
if (Stack->count() <= 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
varName = varName.left(eqIndex);
|
|
|
|
|
|
|
|
const double val = Stack->first();
|
|
|
|
variables[varName] = val;
|
|
|
|
Stack->pop_front();
|
|
|
|
|
|
|
|
statusBar()->message(i18n("Variable %1 set to %2").arg(varName).arg(val), dispTime);
|
|
|
|
|
|
|
|
operateOn = operateOn.right(operateOn.length() - eqIndex - 2);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (variables.contains(varName))
|
|
|
|
{
|
|
|
|
const double val = variables[varName];
|
|
|
|
Stack->prepend(val);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
changeStatusError(i18n("Undefined variable %1").arg(varName));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (removeStartsWith(operateOn, "reqargs"))
|
|
|
|
{
|
|
|
|
if (Stack->count() < 1)
|
|
|
|
return false;
|
|
|
|
double first = Stack->first();
|
|
|
|
Stack->pop_front();
|
|
|
|
if (!parseArgs(first))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (removeStartsWith(operateOn, "stopif"))
|
|
|
|
{
|
|
|
|
if (Stack->count() <= 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
double first = Stack->first();
|
|
|
|
Stack->pop_front();
|
|
|
|
|
|
|
|
if (first == 1)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else if (removeStartsWith(operateOn, "+")) slotAdd();
|
|
|
|
else if (removeStartsWith(operateOn, "-")) slotSubtract();
|
|
|
|
else if (removeStartsWith(operateOn, "*")) slotMultiply();
|
|
|
|
else if (removeStartsWith(operateOn, "/")) slotDivide();
|
|
|
|
else if (removeStartsWith(operateOn, "mod")) slotModulo();
|
|
|
|
else if (removeStartsWith(operateOn, "inverse")) slotInverse();
|
|
|
|
else if (removeStartsWith(operateOn, "e^")) slotRaiseE();
|
|
|
|
else if (removeStartsWith(operateOn, "sqrt")) slotSqrt();
|
|
|
|
else if (removeStartsWith(operateOn, "^2")) slotSquared();
|
|
|
|
else if (removeStartsWith(operateOn, "sin")) slotSine();
|
|
|
|
else if (removeStartsWith(operateOn, "cos")) slotCosine();
|
|
|
|
else if (removeStartsWith(operateOn, "tan")) slotTangent();
|
|
|
|
else if (removeStartsWith(operateOn, "10^")) slotRaiseTen();
|
|
|
|
else if (removeStartsWith(operateOn, "ln")) slotLn();
|
|
|
|
else if (removeStartsWith(operateOn, "!")) slotFactorial();
|
|
|
|
else if (removeStartsWith(operateOn, "^")) slotPower();
|
|
|
|
else if (removeStartsWith(operateOn, "and")) slotAnd();
|
|
|
|
else if (removeStartsWith(operateOn, "xor")) slotXOr();
|
|
|
|
else if (removeStartsWith(operateOn, "or")) slotOr();
|
|
|
|
else if (removeStartsWith(operateOn, "lsh") || removeStartsWith(operateOn, "<<")) slotLsh();
|
|
|
|
else if (removeStartsWith(operateOn, "rsh") || removeStartsWith(operateOn, ">>")) slotRsh();
|
|
|
|
else if (removeStartsWith(operateOn, "at"))
|
|
|
|
{
|
|
|
|
if (Stack->count() < 1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
double index = Stack->first();
|
|
|
|
Stack->pop_front();
|
|
|
|
|
|
|
|
if (index < 0 || index > Stack->count() - 1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Stack->prepend(*Stack->at(index));
|
|
|
|
}
|
|
|
|
else if (removeStartsWith(operateOn, "level"))
|
|
|
|
{
|
|
|
|
if (Stack->count() < 1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
double index = Stack->first() - 1;
|
|
|
|
Stack->pop_front();
|
|
|
|
|
|
|
|
if (index < 0 || index > Stack->count() - 1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
Stack->prepend(*Stack->at(index));
|
|
|
|
}
|
|
|
|
else if (removeStartsWith(operateOn, "curbase"))
|
|
|
|
Stack->prepend((double)base);
|
|
|
|
else if (removeStartsWith(operateOn, "curangle"))
|
|
|
|
Stack->prepend((double)angle);
|
|
|
|
else if (removeStartsWith(operateOn, "curangle"))
|
|
|
|
Stack->prepend((double)(HypButton->isChecked()? 1 : 0));
|
|
|
|
else if (removeStartsWith(operateOn, "clear")) Stack->clear();
|
|
|
|
else if (removeStartsWith(operateOn, "drop")) Stack->pop_front();
|
|
|
|
else if (removeStartsWith(operateOn, "swap")) roll(2);
|
|
|
|
else if (removeStartsWith(operateOn, "rolld"))
|
|
|
|
{
|
|
|
|
if (Stack->count() < 1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
double first = Stack->first();
|
|
|
|
Stack->pop_front();
|
|
|
|
rolld(first);
|
|
|
|
}
|
|
|
|
else if (removeStartsWith(operateOn, "roll"))
|
|
|
|
{
|
|
|
|
if (Stack->count() < 1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
double first = Stack->first();
|
|
|
|
Stack->pop_front();
|
|
|
|
roll(first);
|
|
|
|
}
|
|
|
|
else if (removeStartsWith(operateOn, "setbase"))
|
|
|
|
{
|
|
|
|
if (Stack->count() <= 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
base = (int)Stack->first();
|
|
|
|
switch (base)
|
|
|
|
{
|
|
|
|
case 16:
|
|
|
|
baseGroup->setCurrentItem(0);
|
|
|
|
slotBaseChanged(0);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 10:
|
|
|
|
baseGroup->setCurrentItem(1);
|
|
|
|
slotBaseChanged(1);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
baseGroup->setCurrentItem(2);
|
|
|
|
slotBaseChanged(2);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
baseGroup->setCurrentItem(3);
|
|
|
|
slotBaseChanged(3);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
}
|
|
|
|
else if (removeStartsWith(operateOn, "setangle"))
|
|
|
|
{
|
|
|
|
if (Stack->count() <= 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
angle = (int)Stack->first();
|
|
|
|
angGroup->setCurrentItem(angle);
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
}
|
|
|
|
else if (removeStartsWith(operateOn, "sethyp"))
|
|
|
|
{
|
|
|
|
if (Stack->count() <= 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
HypButton->setChecked(Stack->first() == 1);
|
|
|
|
|
|
|
|
Stack->pop_front();
|
|
|
|
}
|
|
|
|
else if (removeStartsWith(operateOn, "dup2"))
|
|
|
|
slotDup2();
|
|
|
|
else if (removeStartsWith(operateOn, "dup"))
|
|
|
|
{
|
|
|
|
if (Stack->count() > 0)
|
|
|
|
Stack->prepend(Stack->first());
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
bool found = false;
|
|
|
|
// go through commands
|
|
|
|
for (TQMap<TQString, TQString>::Iterator it = formulas.begin(); it != formulas.end() && !found; ++it)
|
|
|
|
{
|
|
|
|
TQString name = it.key();
|
|
|
|
if (removeStartsWith(operateOn, name))
|
|
|
|
{
|
|
|
|
runFormula(name);
|
|
|
|
found = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!found)
|
|
|
|
{
|
|
|
|
changeStatusError(i18n("Unknown command %1").arg(operateOn));
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::keyBindings()
|
|
|
|
{
|
|
|
|
KKeyDialog::configure(actionCollection());
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::configureToolBars()
|
|
|
|
{
|
|
|
|
saveMainWindowSettings(TDEGlobal::config(), "TopLevelWindow");
|
|
|
|
|
|
|
|
KEditToolbar dlg(actionCollection());
|
|
|
|
connect(&dlg, SIGNAL(newToolbarConfig()), SLOT(newToolBarConfig()));
|
|
|
|
|
|
|
|
if (dlg.exec())
|
|
|
|
createGUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
void Mathemagics::newToolBarConfig()
|
|
|
|
{
|
|
|
|
applyMainWindowSettings(TDEGlobal::config(), "TopLevelWindow");
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
|
|
|
EditAction::EditAction(const TQString& text, int accel, const TQObject *receiver, const char *member, TQObject* parent, const char* name)
|
|
|
|
: TDEAction(text, accel, parent, name)
|
|
|
|
{
|
|
|
|
m_receiver = receiver;
|
|
|
|
m_member = member;
|
|
|
|
}
|
|
|
|
|
|
|
|
EditAction::~EditAction()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int EditAction::plug(TQWidget *w, int index)
|
|
|
|
{
|
|
|
|
TDEToolBar *toolBar = (TDEToolBar *)w;
|
|
|
|
int id = TDEAction::getToolButtonID();
|
|
|
|
|
|
|
|
KParanoidLine *comboBox = new KParanoidLine(toolBar, "search edit");
|
|
|
|
toolBar->insertWidget(id, 70, comboBox, index);
|
|
|
|
if (m_receiver)
|
|
|
|
connect(comboBox, SIGNAL(returnPressed()), m_receiver, m_member);
|
|
|
|
|
|
|
|
addContainer(toolBar, id);
|
|
|
|
connect(toolBar, SIGNAL(destroyed()), this, SLOT(slotDestroyed()));
|
|
|
|
toolBar->setItemAutoSized(id, true);
|
|
|
|
m_combo = comboBox;
|
|
|
|
emit plugged();
|
|
|
|
return containerCount() - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditAction::unplug(TQWidget *w)
|
|
|
|
{
|
|
|
|
TDEToolBar *toolBar = (TDEToolBar *)w;
|
|
|
|
int idx = findContainer(w);
|
|
|
|
toolBar->removeItem(menuId(idx));
|
|
|
|
removeContainer(idx);
|
|
|
|
m_combo = 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditAction::clear()
|
|
|
|
{
|
|
|
|
m_combo->clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditAction::append(TQString text)
|
|
|
|
{
|
|
|
|
m_combo->setText(this->text() + text);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditAction::insert(TQString text)
|
|
|
|
{
|
|
|
|
m_combo->insert(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQGuardedPtr<KParanoidLine> EditAction::edit()
|
|
|
|
{
|
|
|
|
return m_combo;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////
|
|
|
|
|
|
|
|
ComboAction::ComboAction(const TQString& text, int accel, const TQObject *receiver, const char *member, TQObject* parent, const char* name)
|
|
|
|
: TDEAction(text, accel, parent, name)
|
|
|
|
{
|
|
|
|
m_receiver = receiver;
|
|
|
|
m_member = member;
|
|
|
|
}
|
|
|
|
|
|
|
|
ComboAction::~ComboAction()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int ComboAction::plug(TQWidget *w, int index)
|
|
|
|
{
|
|
|
|
TDEToolBar *toolBar = (TDEToolBar *)w;
|
|
|
|
|
|
|
|
int id = TDEAction::getToolButtonID();
|
|
|
|
|
|
|
|
TQComboBox *comboBox = new TQComboBox(toolBar, "search edit");
|
|
|
|
toolBar->insertWidget(id, 70, comboBox, index);
|
|
|
|
if (m_receiver)
|
|
|
|
connect(comboBox, SIGNAL(returnPressed()), m_receiver, m_member);
|
|
|
|
|
|
|
|
addContainer(toolBar, id);
|
|
|
|
connect(toolBar, SIGNAL(destroyed()), this, SLOT(slotDestroyed()));
|
|
|
|
toolBar->setItemAutoSized(id, true);
|
|
|
|
m_combo = comboBox;
|
|
|
|
emit plugged();
|
|
|
|
return containerCount() - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ComboAction::unplug(TQWidget *w)
|
|
|
|
{
|
|
|
|
TDEToolBar *toolBar = (TDEToolBar *)w;
|
|
|
|
int idx = findContainer(w);
|
|
|
|
toolBar->removeItem(menuId(idx));
|
|
|
|
|
|
|
|
removeContainer(idx);
|
|
|
|
m_combo = 0L;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQGuardedPtr<TQComboBox> ComboAction::combo()
|
|
|
|
{
|
|
|
|
return m_combo;
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "mathemagics.moc"
|