|
|
|
/*
|
|
|
|
* mainwindow.cpp - part of abakus
|
|
|
|
* Copyright (C) 2004, 2005 Michael Pyne <michael.pyne@kdemail.net>
|
|
|
|
*
|
|
|
|
* 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 "mainwindow.h"
|
|
|
|
#include "abakuscommon.h"
|
|
|
|
|
|
|
|
#include <kaccel.h>
|
|
|
|
#include <kmenubar.h>
|
|
|
|
#include <kaction.h>
|
|
|
|
#include <kstdaction.h>
|
|
|
|
#include <kshortcut.h>
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kconfig.h>
|
|
|
|
#include <kglobal.h>
|
|
|
|
#include <kconfigbase.h>
|
|
|
|
#include <kactionclasses.h>
|
|
|
|
#include <kinputdialog.h>
|
|
|
|
|
|
|
|
#include <tqlayout.h>
|
|
|
|
#include <tqvbox.h>
|
|
|
|
#include <tqhbox.h>
|
|
|
|
#include <tqradiobutton.h>
|
|
|
|
#include <tqbuttongroup.h>
|
|
|
|
#include <tqsplitter.h>
|
|
|
|
|
|
|
|
#include "editor.h"
|
|
|
|
#include "evaluator.h"
|
|
|
|
#include "function.h"
|
|
|
|
#include "resultlistview.h"
|
|
|
|
#include "resultlistviewtext.h"
|
|
|
|
#include "valuemanager.h"
|
|
|
|
#include "node.h"
|
|
|
|
#include "rpnmuncher.h"
|
|
|
|
#include "dcopIface.h"
|
|
|
|
#include "abakuslistview.h"
|
|
|
|
#include "result.h"
|
|
|
|
|
|
|
|
MainWindow::MainWindow() : KMainWindow(0, "abakus-mainwindow"), m_popup(0), m_insert(false)
|
|
|
|
{
|
|
|
|
m_mainSplitter = new TQSplitter(this);
|
|
|
|
TQWidget *box = new TQWidget(m_mainSplitter);
|
|
|
|
TQVBoxLayout *tqlayout = new TQVBoxLayout(box);
|
|
|
|
m_layout = tqlayout;
|
|
|
|
tqlayout->setSpacing(6);
|
|
|
|
tqlayout->setMargin(6);
|
|
|
|
|
|
|
|
TQWidget *configBox = new TQWidget(box);
|
|
|
|
tqlayout->addWidget(configBox);
|
|
|
|
|
|
|
|
TQHBoxLayout *configLayout = new TQHBoxLayout(configBox);
|
|
|
|
|
|
|
|
configLayout->addWidget(new TQWidget(configBox));
|
|
|
|
|
|
|
|
TQLabel *label = new TQLabel(i18n("History: "), configBox);
|
|
|
|
label->tqsetAlignment(AlignCenter);
|
|
|
|
configLayout->addWidget(label);
|
|
|
|
|
|
|
|
TQButtonGroup *buttonGroup = new TQButtonGroup(0);
|
|
|
|
|
|
|
|
TQWidget *buttonGroupBox = new TQWidget(configBox);
|
|
|
|
TQHBoxLayout *buttonGroupLayout = new TQHBoxLayout(buttonGroupBox);
|
|
|
|
buttonGroupLayout->addStretch(0);
|
|
|
|
|
|
|
|
configLayout->addWidget(buttonGroupBox);
|
|
|
|
|
|
|
|
m_degrees = new TQRadioButton(i18n("&Degrees"), buttonGroupBox);
|
|
|
|
buttonGroup->insert(m_degrees);
|
|
|
|
buttonGroupLayout->addWidget(m_degrees);
|
|
|
|
slotDegrees();
|
|
|
|
connect(m_degrees, TQT_SIGNAL(clicked()), TQT_SLOT(slotDegrees()));
|
|
|
|
|
|
|
|
m_radians = new TQRadioButton(i18n("&Radians"), buttonGroupBox);
|
|
|
|
buttonGroup->insert(m_radians);
|
|
|
|
buttonGroupLayout->addWidget(m_radians);
|
|
|
|
connect(m_radians, TQT_SIGNAL(clicked()), TQT_SLOT(slotRadians()));
|
|
|
|
|
|
|
|
m_history = new TQVBox(box);
|
|
|
|
tqlayout->addWidget(m_history);
|
|
|
|
m_history->setSpacing(6);
|
|
|
|
m_history->setMargin(0);
|
|
|
|
|
|
|
|
m_result = new ResultListView(m_history);
|
|
|
|
m_result->setSelectionMode(TQListView::NoSelection);
|
|
|
|
m_result->setHScrollBarMode(ResultListView::AlwaysOff);
|
|
|
|
connect(m_result, TQT_SIGNAL(signalEntrySelected(const TQString &)),
|
|
|
|
TQT_SLOT(slotEntrySelected(const TQString &)));
|
|
|
|
connect(m_result, TQT_SIGNAL(signalResultSelected(const TQString &)),
|
|
|
|
TQT_SLOT(slotResultSelected(const TQString &)));
|
|
|
|
|
|
|
|
m_history->setStretchFactor(m_result, 1);
|
|
|
|
tqlayout->setStretchFactor(m_history, 1);
|
|
|
|
|
|
|
|
TQHBox *editBox = new TQHBox(box);
|
|
|
|
tqlayout->addWidget(editBox);
|
|
|
|
editBox->setSpacing(6);
|
|
|
|
|
|
|
|
m_edit = new Editor(editBox);
|
|
|
|
m_edit->setFocus();
|
|
|
|
editBox->setStretchFactor(m_edit, 1);
|
|
|
|
|
|
|
|
KPushButton *evalButton = new KPushButton(i18n("&Evaluate"), editBox);
|
|
|
|
|
|
|
|
connect(evalButton, TQT_SIGNAL(clicked()), TQT_SLOT(slotEvaluate()));
|
|
|
|
|
|
|
|
connect(m_edit, TQT_SIGNAL(returnPressed()), TQT_SLOT(slotReturnPressed()));
|
|
|
|
connect(m_edit, TQT_SIGNAL(textChanged()), TQT_SLOT(slotTextChanged()));
|
|
|
|
|
|
|
|
m_listSplitter = new TQSplitter(Qt::Vertical, m_mainSplitter);
|
|
|
|
m_fnList = new FunctionListView(m_listSplitter);
|
|
|
|
m_fnList->addColumn("Functions");
|
|
|
|
m_fnList->addColumn("Value");
|
|
|
|
|
|
|
|
m_varList = new VariableListView(m_listSplitter);
|
|
|
|
m_varList->addColumn("Variables");
|
|
|
|
m_varList->addColumn("Value");
|
|
|
|
|
|
|
|
connect(FunctionManager::instance(), TQT_SIGNAL(signalFunctionAdded(const TQString &)),
|
|
|
|
this, TQT_SLOT(slotNewFunction(const TQString &)));
|
|
|
|
connect(FunctionManager::instance(), TQT_SIGNAL(signalFunctionRemoved(const TQString &)),
|
|
|
|
this, TQT_SLOT(slotRemoveFunction(const TQString &)));
|
|
|
|
|
|
|
|
connect(ValueManager::instance(), TQT_SIGNAL(signalValueAdded(const TQString &, Abakus::number_t)),
|
|
|
|
this, TQT_SLOT(slotNewValue(const TQString &, Abakus::number_t)));
|
|
|
|
connect(ValueManager::instance(), TQT_SIGNAL(signalValueChanged(const TQString &, Abakus::number_t)),
|
|
|
|
this, TQT_SLOT(slotChangeValue(const TQString &, Abakus::number_t)));
|
|
|
|
connect(ValueManager::instance(), TQT_SIGNAL(signalValueRemoved(const TQString &)),
|
|
|
|
this, TQT_SLOT(slotRemoveValue(const TQString &)));
|
|
|
|
|
|
|
|
setupLayout();
|
|
|
|
|
|
|
|
setCentralWidget(m_mainSplitter);
|
|
|
|
|
|
|
|
#if KDE_IS_VERSION(3,4,89)
|
|
|
|
setupGUI(TQSize(450, 400), Keys | StatusBar | Save | Create);
|
|
|
|
#else
|
|
|
|
setupGUI(Keys | StatusBar | Save | Create);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
m_dcopInterface = new AbakusIface();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MainWindow::inRPNMode() const
|
|
|
|
{
|
|
|
|
return action<KToggleAction>("toggleExpressionMode")->isChecked();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MainWindow::eventFilter(TQObject *o, TQEvent *e)
|
|
|
|
{
|
|
|
|
return KMainWindow::eventFilter(o, e);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool MainWindow::queryExit()
|
|
|
|
{
|
|
|
|
saveConfig();
|
|
|
|
return KMainWindow::queryExit();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::contextMenuEvent(TQContextMenuEvent *e)
|
|
|
|
{
|
|
|
|
static KPopupMenu *popup = 0;
|
|
|
|
|
|
|
|
if(!popup) {
|
|
|
|
popup = new KPopupMenu(this);
|
|
|
|
action("options_show_menubar")->plug(popup);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!action<KToggleAction>("options_show_menubar")->isChecked())
|
|
|
|
popup->popup(e->globalPos());
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::polish()
|
|
|
|
{
|
|
|
|
KMainWindow::polish();
|
|
|
|
loadConfig();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotReturnPressed()
|
|
|
|
{
|
|
|
|
TQString text = m_edit->text();
|
|
|
|
|
|
|
|
text.replace("\n", "");
|
|
|
|
|
|
|
|
m_edit->appendHistory(text);
|
|
|
|
|
|
|
|
// Item to insert after
|
|
|
|
ResultListViewText *after = m_result->lastItem();
|
|
|
|
|
|
|
|
// Expand $foo references.
|
|
|
|
TQString str = interpolateExpression(text, after);
|
|
|
|
|
|
|
|
TQString resultVal;
|
|
|
|
ResultListViewText *item;
|
|
|
|
|
|
|
|
if(str.isNull())
|
|
|
|
return; // Error already has been posted
|
|
|
|
|
|
|
|
m_insert = false; // Assume we failed
|
|
|
|
|
|
|
|
if(inRPNMode()) {
|
|
|
|
// We're in RPN mode.
|
|
|
|
Abakus::number_t result = RPNParser::rpnParseString(str);
|
|
|
|
|
|
|
|
if(!RPNParser::wasError()) {
|
|
|
|
resultVal = result.toString();
|
|
|
|
ValueManager::instance()->setValue("ans", result);
|
|
|
|
m_insert = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_insert = false;
|
|
|
|
resultVal = i18n("Error: %1").tqarg(RPNParser::errorString());
|
|
|
|
}
|
|
|
|
|
|
|
|
// Skip creating list view items if in compact mode.
|
|
|
|
if(!m_history->isShown()) {
|
|
|
|
m_edit->setText(resultVal);
|
|
|
|
TQTimer::singleShot(0, m_edit, TQT_SLOT(selectAll()));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
item = new ResultListViewText(m_result, str, resultVal, after, false);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
// Check to see if it's just a function name, if so, add (ans).
|
|
|
|
if(FunctionManager::instance()->isFunction(str))
|
|
|
|
str += " ans";
|
|
|
|
|
|
|
|
// Add right parentheses as needed to balance out the expression.
|
|
|
|
int parenLevel = getParenthesesLevel(str);
|
|
|
|
for(int i = 0; i < parenLevel; ++i)
|
|
|
|
str += ')';
|
|
|
|
|
|
|
|
Abakus::number_t result = parseString(str.latin1());
|
|
|
|
|
|
|
|
bool compact = !m_history->isShown();
|
|
|
|
|
|
|
|
switch(Result::lastResult()->type()) {
|
|
|
|
case Result::Value:
|
|
|
|
resultVal = result.toString();
|
|
|
|
|
|
|
|
ValueManager::instance()->setValue("ans", result);
|
|
|
|
if(!compact)
|
|
|
|
item = new ResultListViewText(m_result, str, result, after, false);
|
|
|
|
|
|
|
|
m_insert = true;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Result::Null: // OK, no result to speak of
|
|
|
|
resultVal = "OK";
|
|
|
|
if(!compact)
|
|
|
|
item = new ResultListViewText(m_result, str, resultVal, after, true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
resultVal = Result::lastResult()->message();
|
|
|
|
if(!compact)
|
|
|
|
item = new ResultListViewText(m_result, str, resultVal, after, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Skip creating list view items if in compact mode.
|
|
|
|
if(compact) {
|
|
|
|
m_edit->setText(resultVal);
|
|
|
|
TQTimer::singleShot(0, m_edit, TQT_SLOT(selectAll()));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_edit->setText(text);
|
|
|
|
|
|
|
|
m_result->setCurrentItem(item);
|
|
|
|
m_result->ensureItemVisible(item);
|
|
|
|
|
|
|
|
TQTimer::singleShot(0, m_edit, TQT_SLOT(selectAll()));
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotTextChanged()
|
|
|
|
{
|
|
|
|
TQString str = m_edit->text();
|
|
|
|
|
|
|
|
if(str.length() == 1 && m_insert) {
|
|
|
|
m_insert = false;
|
|
|
|
|
|
|
|
// Don't do anything if in RPN Mode.
|
|
|
|
if(inRPNMode())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(str.find(TQRegExp("^[-+*/^]")) != -1) {
|
|
|
|
m_edit->setText("ans " + str + " ");
|
|
|
|
m_edit->moveCursor(TQTextEdit::MoveEnd, false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotEvaluate()
|
|
|
|
{
|
|
|
|
slotReturnPressed();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotUpdateSize()
|
|
|
|
{
|
|
|
|
if(m_newSize != TQSize(0, 0))
|
|
|
|
resize(m_newSize);
|
|
|
|
else
|
|
|
|
resize(width(), tqminimumSize().height());
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotDegrees()
|
|
|
|
{
|
|
|
|
setTrigMode(Abakus::Degrees);
|
|
|
|
m_degrees->setChecked(true);
|
|
|
|
if(action("setDegreesMode"))
|
|
|
|
action<KToggleAction>("setDegreesMode")->setChecked(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotRadians()
|
|
|
|
{
|
|
|
|
setTrigMode(Abakus::Radians);
|
|
|
|
m_radians->setChecked(true);
|
|
|
|
if(action("setRadiansMode"))
|
|
|
|
action<KToggleAction>("setRadiansMode")->setChecked(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
int MainWindow::getParenthesesLevel(const TQString &str)
|
|
|
|
{
|
|
|
|
int level = 0;
|
|
|
|
|
|
|
|
for(unsigned i = 0; i < str.length(); ++i)
|
|
|
|
if(str[i] == '(')
|
|
|
|
++level;
|
|
|
|
else if(str[i] == ')')
|
|
|
|
--level;
|
|
|
|
|
|
|
|
return level;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::loadConfig()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
KConfigGroup config(KGlobal::config(), "Settings");
|
|
|
|
|
|
|
|
TQString mode = config.readEntry("Trigonometric mode", "Degrees");
|
|
|
|
if(mode == "Degrees") {
|
|
|
|
setTrigMode(Abakus::Degrees);
|
|
|
|
m_degrees->setChecked(true);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
setTrigMode(Abakus::Radians);
|
|
|
|
m_radians->setChecked(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool useRPN = config.readBoolEntry("Use RPN Mode", false);
|
|
|
|
action<KToggleAction>("toggleExpressionMode")->setChecked(useRPN);
|
|
|
|
|
|
|
|
int precision = config.readNumEntry("Decimal Precision", -1);
|
|
|
|
if(precision < -1 || precision > 75)
|
|
|
|
precision = -1;
|
|
|
|
|
|
|
|
Abakus::m_prec = precision;
|
|
|
|
selectCorrectPrecisionAction();
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
KConfigGroup config(KGlobal::config(), "Variables");
|
|
|
|
|
|
|
|
TQStringList list = config.readListEntry("Saved Variables");
|
|
|
|
for(TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
|
|
|
|
TQStringList values = TQStringList::split('=', *it);
|
|
|
|
if(values.count() != 2) {
|
|
|
|
kdWarning() << "Your configuration file has somehow been corrupted!\n";
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
ValueManager::instance()->setValue(values[0], Abakus::number_t(values[1].latin1()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
KConfigGroup config(KGlobal::config(), "GUI");
|
|
|
|
|
|
|
|
bool showHistory = config.readBoolEntry("ShowHistory", true);
|
|
|
|
action<KToggleAction>("toggleHistoryList")->setChecked(showHistory);
|
|
|
|
m_history->setShown(showHistory);
|
|
|
|
|
|
|
|
bool showFunctions = config.readBoolEntry("ShowFunctions", true);
|
|
|
|
action<KToggleAction>("toggleFunctionList")->setChecked(showFunctions);
|
|
|
|
m_fnList->setShown(showFunctions);
|
|
|
|
|
|
|
|
bool showVariables = config.readBoolEntry("ShowVariables", true);
|
|
|
|
action<KToggleAction>("toggleVariableList")->setChecked(showVariables);
|
|
|
|
m_varList->setShown(showVariables);
|
|
|
|
|
|
|
|
bool compactMode = config.readBoolEntry("InCompactMode", false);
|
|
|
|
compactMode = compactMode || !showHistory;
|
|
|
|
action<KToggleAction>("toggleCompactMode")->setChecked(compactMode);
|
|
|
|
|
|
|
|
if(compactMode)
|
|
|
|
TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(slotToggleCompactMode()));
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
KConfigGroup config(KGlobal::config(), "Functions");
|
|
|
|
|
|
|
|
TQStringList fnList = config.readListEntry("FunctionList");
|
|
|
|
for(TQStringList::ConstIterator it = fnList.begin(); it != fnList.end(); ++it)
|
|
|
|
parseString((*it).ascii()); // Run the function definitions through the parser
|
|
|
|
}
|
|
|
|
|
|
|
|
populateListViews();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::saveConfig()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
KConfigGroup config(KGlobal::config(), "Settings");
|
|
|
|
|
|
|
|
config.writeEntry("Trigonometric mode",
|
|
|
|
trigMode() == Abakus::Degrees
|
|
|
|
? "Degrees"
|
|
|
|
: "Radians");
|
|
|
|
|
|
|
|
config.writeEntry("Use RPN Mode", inRPNMode());
|
|
|
|
config.writeEntry("Decimal Precision", Abakus::m_prec);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
KConfigGroup config(KGlobal::config(), "Variables");
|
|
|
|
|
|
|
|
TQStringList list;
|
|
|
|
TQStringList values = ValueManager::instance()->valueNames();
|
|
|
|
TQStringList::ConstIterator it = values.begin();
|
|
|
|
|
|
|
|
// Set precision to max for most accuracy
|
|
|
|
Abakus::m_prec = 75;
|
|
|
|
|
|
|
|
for(; it != values.end(); ++it) {
|
|
|
|
if(ValueManager::instance()->isValueReadOnly(*it))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
list += TQString("%1=%2")
|
|
|
|
.tqarg(*it)
|
|
|
|
.tqarg(ValueManager::instance()->value(*it).toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
config.writeEntry("Saved Variables", list);
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
KConfigGroup config(KGlobal::config(), "GUI");
|
|
|
|
bool inCompactMode = action<KToggleAction>("toggleCompactMode")->isChecked();
|
|
|
|
|
|
|
|
config.writeEntry("InCompactMode", inCompactMode);
|
|
|
|
|
|
|
|
if(!inCompactMode) {
|
|
|
|
config.writeEntry("ShowHistory", m_history->isShown());
|
|
|
|
config.writeEntry("ShowFunctions", m_fnList->isShown());
|
|
|
|
config.writeEntry("ShowVariables", m_varList->isShown());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
config.writeEntry("ShowHistory", m_wasHistoryShown);
|
|
|
|
config.writeEntry("ShowFunctions", m_wasFnShown);
|
|
|
|
config.writeEntry("ShowVariables", m_wasVarShown);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
KConfigGroup config(KGlobal::config(), "Functions");
|
|
|
|
|
|
|
|
FunctionManager *manager = FunctionManager::instance();
|
|
|
|
|
|
|
|
TQStringList userFunctions = manager->functionList(FunctionManager::UserDefined);
|
|
|
|
TQStringList saveList;
|
|
|
|
|
|
|
|
for(TQStringList::ConstIterator it = userFunctions.begin(); it != userFunctions.end(); ++it) {
|
|
|
|
UnaryFunction *fn = dynamic_cast<UnaryFunction *>(manager->function(*it)->userFn->fn);
|
|
|
|
TQString var = manager->function(*it)->userFn->varName;
|
|
|
|
TQString expr = fn->operand()->infixString();
|
|
|
|
|
|
|
|
saveList += TQString("set %1(%2) = %3").tqarg(*it).tqarg(var).tqarg(expr);
|
|
|
|
}
|
|
|
|
|
|
|
|
config.writeEntry("FunctionList", saveList);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::setupLayout()
|
|
|
|
{
|
|
|
|
KActionCollection *ac = actionCollection();
|
|
|
|
|
|
|
|
KStdAction::quit(TQT_TQOBJECT(kapp), TQT_SLOT(quit()), ac);
|
|
|
|
KStdAction::showMenubar(TQT_TQOBJECT(this), TQT_SLOT(slotToggleMenuBar()), ac);
|
|
|
|
|
|
|
|
KToggleAction *ta = new KToggleAction(i18n("&Degrees"), SHIFT + ALT + Key_D, TQT_TQOBJECT(this), TQT_SLOT(slotDegrees()), ac, "setDegreesMode");
|
|
|
|
ta->setExclusiveGroup("TrigMode");
|
|
|
|
ta->setChecked(trigMode() == Abakus::Degrees);
|
|
|
|
|
|
|
|
ta = new KToggleAction(i18n("&Radians"), SHIFT + ALT + Key_R, TQT_TQOBJECT(this), TQT_SLOT(slotRadians()), ac, "setRadiansMode");
|
|
|
|
ta->setExclusiveGroup("TrigMode");
|
|
|
|
ta->setChecked(trigMode() == Abakus::Radians);
|
|
|
|
|
|
|
|
ta = new KToggleAction(i18n("Show &History List"), SHIFT + ALT + Key_H, TQT_TQOBJECT(this), TQT_SLOT(slotToggleHistoryList()), ac, "toggleHistoryList");
|
|
|
|
ta->setChecked(true);
|
|
|
|
|
|
|
|
ta = new KToggleAction(i18n("Show &Variables"), SHIFT + ALT + Key_V, TQT_TQOBJECT(this), TQT_SLOT(slotToggleVariableList()), ac, "toggleVariableList");
|
|
|
|
ta->setChecked(true);
|
|
|
|
|
|
|
|
ta = new KToggleAction(i18n("Show &Functions"), SHIFT + ALT + Key_F, TQT_TQOBJECT(this), TQT_SLOT(slotToggleFunctionList()), ac, "toggleFunctionList");
|
|
|
|
ta->setChecked(true);
|
|
|
|
|
|
|
|
ta = new KToggleAction(i18n("Activate &Compact Mode"), SHIFT + ALT + Key_C, TQT_TQOBJECT(this), TQT_SLOT(slotToggleCompactMode()), ac, "toggleCompactMode");
|
|
|
|
ta->setChecked(false);
|
|
|
|
|
|
|
|
ta = new KToggleAction(i18n("Use R&PN Mode"), SHIFT + ALT + Key_P, TQT_TQOBJECT(this), TQT_SLOT(slotToggleExpressionMode()), ac, "toggleExpressionMode");
|
|
|
|
ta->setChecked(false);
|
|
|
|
|
|
|
|
// Precision actions.
|
|
|
|
ta = new KToggleAction(i18n("&Automatic Precision"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotPrecisionAuto()), ac, "precisionAuto");
|
|
|
|
ta->setExclusiveGroup("Precision");
|
|
|
|
ta->setChecked(true);
|
|
|
|
|
|
|
|
ta = new KToggleAction(i18n("&3 Decimal Digits"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotPrecision3()), ac, "precision3");
|
|
|
|
ta->setExclusiveGroup("Precision");
|
|
|
|
ta->setChecked(false);
|
|
|
|
|
|
|
|
ta = new KToggleAction(i18n("&8 Decimal Digits"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotPrecision8()), ac, "precision8");
|
|
|
|
ta->setExclusiveGroup("Precision");
|
|
|
|
ta->setChecked(false);
|
|
|
|
|
|
|
|
ta = new KToggleAction(i18n("&15 Decimal Digits"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotPrecision15()), ac, "precision15");
|
|
|
|
ta->setExclusiveGroup("Precision");
|
|
|
|
ta->setChecked(false);
|
|
|
|
|
|
|
|
ta = new KToggleAction(i18n("&50 Decimal Digits"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotPrecision50()), ac, "precision50");
|
|
|
|
ta->setExclusiveGroup("Precision");
|
|
|
|
ta->setChecked(false);
|
|
|
|
|
|
|
|
ta = new KToggleAction(i18n("C&ustom Precision..."), 0, TQT_TQOBJECT(this), TQT_SLOT(slotPrecisionCustom()), ac, "precisionCustom");
|
|
|
|
ta->setExclusiveGroup("Precision");
|
|
|
|
ta->setChecked(false);
|
|
|
|
|
|
|
|
new KAction(i18n("Clear &History"), "editclear", SHIFT + ALT + Key_L, TQT_TQOBJECT(m_result), TQT_SLOT(clear()), ac, "clearHistory");
|
|
|
|
|
|
|
|
new KAction(i18n("Select Editor"), "goto", Key_F6, TQT_TQOBJECT(m_edit), TQT_SLOT(setFocus()), ac, "select_edit");
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::populateListViews()
|
|
|
|
{
|
|
|
|
TQStringList values = ValueManager::instance()->valueNames();
|
|
|
|
|
|
|
|
Abakus::number_t value = ValueManager::instance()->value("pi");
|
|
|
|
new ValueListViewItem(m_varList, "pi", value);
|
|
|
|
|
|
|
|
value = ValueManager::instance()->value("e");
|
|
|
|
new ValueListViewItem(m_varList, "e", value);
|
|
|
|
}
|
|
|
|
|
|
|
|
KAction *MainWindow::action(const char *key) const
|
|
|
|
{
|
|
|
|
return actionCollection()->action(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotEntrySelected(const TQString &text)
|
|
|
|
{
|
|
|
|
m_edit->setText(text);
|
|
|
|
m_edit->moveCursor(TQTextEdit::MoveEnd, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotResultSelected(const TQString &text)
|
|
|
|
{
|
|
|
|
m_edit->insert(text);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotToggleMenuBar()
|
|
|
|
{
|
|
|
|
menuBar()->setShown(!menuBar()->isShown());
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotToggleFunctionList()
|
|
|
|
{
|
|
|
|
bool show = action<KToggleAction>("toggleFunctionList")->isChecked();
|
|
|
|
m_fnList->setShown(show);
|
|
|
|
|
|
|
|
if(!m_history->isShown()) {
|
|
|
|
m_history->setShown(true);
|
|
|
|
action<KToggleAction>("toggleHistoryList")->setChecked(true);
|
|
|
|
slotToggleHistoryList();
|
|
|
|
}
|
|
|
|
|
|
|
|
action<KToggleAction>("toggleCompactMode")->setChecked(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotToggleVariableList()
|
|
|
|
{
|
|
|
|
bool show = action<KToggleAction>("toggleVariableList")->isChecked();
|
|
|
|
m_varList->setShown(show);
|
|
|
|
|
|
|
|
if(!m_history->isShown()) {
|
|
|
|
m_history->setShown(true);
|
|
|
|
action<KToggleAction>("toggleHistoryList")->setChecked(true);
|
|
|
|
slotToggleHistoryList();
|
|
|
|
}
|
|
|
|
|
|
|
|
action<KToggleAction>("toggleCompactMode")->setChecked(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotToggleHistoryList()
|
|
|
|
{
|
|
|
|
bool show = action<KToggleAction>("toggleHistoryList")->isChecked();
|
|
|
|
m_history->setShown(show);
|
|
|
|
|
|
|
|
action<KToggleAction>("toggleCompactMode")->setChecked(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotNewFunction(const TQString &name)
|
|
|
|
{
|
|
|
|
UserFunction *userFn = FunctionManager::instance()->function(name)->userFn;
|
|
|
|
UnaryFunction *fn = dynamic_cast<UnaryFunction *>(userFn->fn);
|
|
|
|
TQString fnName = TQString("%1(%2)").tqarg(name, userFn->varName);
|
|
|
|
TQString expr = fn->operand()->infixString();
|
|
|
|
|
|
|
|
new KListViewItem(m_fnList, fnName, expr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotRemoveFunction(const TQString &name)
|
|
|
|
{
|
|
|
|
UserFunction *userFn = FunctionManager::instance()->function(name)->userFn;
|
|
|
|
TQString fnName = TQString("%1(%2)").tqarg(name, userFn->varName);
|
|
|
|
|
|
|
|
TQListViewItem *item = 0;
|
|
|
|
while((item = m_fnList->findItem(fnName, 0)) != 0)
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotNewValue(const TQString &name, Abakus::number_t value)
|
|
|
|
{
|
|
|
|
new ValueListViewItem(m_varList, name, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotChangeValue(const TQString &name, Abakus::number_t value)
|
|
|
|
{
|
|
|
|
ValueListViewItem *item = static_cast<ValueListViewItem *>(m_varList->findItem(name, 0));
|
|
|
|
|
|
|
|
if(item)
|
|
|
|
item->valueChanged(value);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotRemoveValue(const TQString &name)
|
|
|
|
{
|
|
|
|
delete m_varList->findItem(name, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotToggleCompactMode()
|
|
|
|
{
|
|
|
|
if(action<KToggleAction>("toggleCompactMode")->isChecked()) {
|
|
|
|
m_wasFnShown = m_fnList->isShown();
|
|
|
|
m_wasVarShown = m_varList->isShown();
|
|
|
|
m_wasHistoryShown = m_history->isShown();
|
|
|
|
|
|
|
|
m_fnList->setShown(false);
|
|
|
|
m_varList->setShown(false);
|
|
|
|
m_history->setShown(false);
|
|
|
|
|
|
|
|
action<KToggleAction>("toggleFunctionList")->setChecked(false);
|
|
|
|
action<KToggleAction>("toggleVariableList")->setChecked(false);
|
|
|
|
action<KToggleAction>("toggleHistoryList")->setChecked(false);
|
|
|
|
|
|
|
|
m_oldSize = size();
|
|
|
|
m_newSize = TQSize(0, 0);
|
|
|
|
TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(slotUpdateSize()));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
m_fnList->setShown(m_wasFnShown);
|
|
|
|
m_varList->setShown(m_wasVarShown);
|
|
|
|
m_history->setShown(m_wasHistoryShown);
|
|
|
|
|
|
|
|
action<KToggleAction>("toggleFunctionList")->setChecked(m_wasFnShown);
|
|
|
|
action<KToggleAction>("toggleVariableList")->setChecked(m_wasVarShown);
|
|
|
|
action<KToggleAction>("toggleHistoryList")->setChecked(m_wasHistoryShown);
|
|
|
|
|
|
|
|
m_newSize = m_oldSize;
|
|
|
|
TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(slotUpdateSize()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotToggleExpressionMode()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString MainWindow::interpolateExpression(const TQString &text, ResultListViewText *after)
|
|
|
|
{
|
|
|
|
TQString str(text);
|
|
|
|
TQRegExp stackRE("\\$\\d+");
|
|
|
|
int pos;
|
|
|
|
|
|
|
|
while((pos = stackRE.search(str)) != -1) {
|
|
|
|
TQString stackStr = stackRE.cap();
|
|
|
|
Abakus::number_t value;
|
|
|
|
unsigned numPos = stackStr.mid(1).toUInt();
|
|
|
|
|
|
|
|
if(!m_result->getStackValue(numPos, value)) {
|
|
|
|
new ResultListViewText(m_result, text, i18n("Marker %1 isn't set").tqarg(stackStr), after, true);
|
|
|
|
return TQString();
|
|
|
|
}
|
|
|
|
|
|
|
|
str.replace(pos, stackStr.length(), value.toString());
|
|
|
|
}
|
|
|
|
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotPrecisionAuto()
|
|
|
|
{
|
|
|
|
Abakus::m_prec = -1;
|
|
|
|
redrawResults();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotPrecision3()
|
|
|
|
{
|
|
|
|
Abakus::m_prec = 3;
|
|
|
|
redrawResults();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotPrecision8()
|
|
|
|
{
|
|
|
|
Abakus::m_prec = 8;
|
|
|
|
redrawResults();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotPrecision15()
|
|
|
|
{
|
|
|
|
Abakus::m_prec = 15;
|
|
|
|
redrawResults();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotPrecision50()
|
|
|
|
{
|
|
|
|
Abakus::m_prec = 50;
|
|
|
|
redrawResults();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::slotPrecisionCustom()
|
|
|
|
{
|
|
|
|
bool ok = false;
|
|
|
|
int precision = KInputDialog::getInteger(i18n("Select number of decimal digits to display"),
|
|
|
|
i18n("Decimal precision:"), Abakus::m_prec, 0, 75, 1, &ok, this);
|
|
|
|
|
|
|
|
if(ok) {
|
|
|
|
Abakus::m_prec = precision;
|
|
|
|
redrawResults();
|
|
|
|
}
|
|
|
|
|
|
|
|
selectCorrectPrecisionAction();
|
|
|
|
}
|
|
|
|
|
|
|
|
void MainWindow::redrawResults()
|
|
|
|
{
|
|
|
|
TQListViewItemIterator it(m_result);
|
|
|
|
|
|
|
|
while(it.current()) {
|
|
|
|
static_cast<ResultListViewText *>(it.current())->precisionChanged();
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
it = TQListViewItemIterator (m_varList);
|
|
|
|
|
|
|
|
while(it.current()) {
|
|
|
|
static_cast<ValueListViewItem *>(it.current())->valueChanged();
|
|
|
|
++it;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Because of the way we implemented the menu, it is possible to deselect
|
|
|
|
// every possibility, so make sure we have at least one selected.
|
|
|
|
selectCorrectPrecisionAction();
|
|
|
|
}
|
|
|
|
|
|
|
|
// This function selects the correct precision action based on the value of
|
|
|
|
// Abakus::m_prec. Useful for loading settings, or for custom precision
|
|
|
|
// selection.
|
|
|
|
void MainWindow::selectCorrectPrecisionAction()
|
|
|
|
{
|
|
|
|
switch(Abakus::m_prec) {
|
|
|
|
case 3:
|
|
|
|
action<KToggleAction>("precision3")->setChecked(true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 8:
|
|
|
|
action<KToggleAction>("precision8")->setChecked(true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 15:
|
|
|
|
action<KToggleAction>("precision15")->setChecked(true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 50:
|
|
|
|
action<KToggleAction>("precision50")->setChecked(true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case -1:
|
|
|
|
action<KToggleAction>("precisionAuto")->setChecked(true);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
action<KToggleAction>("precisionCustom")->setChecked(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "mainwindow.moc"
|
|
|
|
|
|
|
|
// vim: set et ts=8 sw=4:
|