AbaKus – a complex calculator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

826 lines
25KB

  1. /*
  2. * mainwindow.cpp - part of abakus
  3. * Copyright (C) 2004, 2005 Michael Pyne <michael.pyne@kdemail.net>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19. #include "mainwindow.h"
  20. #include "abakuscommon.h"
  21. #include <kaccel.h>
  22. #include <kmenubar.h>
  23. #include <kaction.h>
  24. #include <kstdaction.h>
  25. #include <kshortcut.h>
  26. #include <kdebug.h>
  27. #include <tdeconfig.h>
  28. #include <kglobal.h>
  29. #include <tdeconfigbase.h>
  30. #include <kactionclasses.h>
  31. #include <kinputdialog.h>
  32. #include <tqlayout.h>
  33. #include <tqvbox.h>
  34. #include <tqhbox.h>
  35. #include <tqradiobutton.h>
  36. #include <tqbuttongroup.h>
  37. #include <tqsplitter.h>
  38. #include "editor.h"
  39. #include "evaluator.h"
  40. #include "function.h"
  41. #include "resultlistview.h"
  42. #include "resultlistviewtext.h"
  43. #include "valuemanager.h"
  44. #include "node.h"
  45. #include "rpnmuncher.h"
  46. #include "dcopIface.h"
  47. #include "abakuslistview.h"
  48. #include "result.h"
  49. MainWindow::MainWindow() : TDEMainWindow(0, "abakus-mainwindow"), m_popup(0), m_insert(false)
  50. {
  51. m_mainSplitter = new TQSplitter(this);
  52. TQWidget *box = new TQWidget(m_mainSplitter);
  53. TQVBoxLayout *layout = new TQVBoxLayout(box);
  54. m_layout = layout;
  55. layout->setSpacing(6);
  56. layout->setMargin(6);
  57. TQWidget *configBox = new TQWidget(box);
  58. layout->addWidget(configBox);
  59. TQHBoxLayout *configLayout = new TQHBoxLayout(configBox);
  60. configLayout->addWidget(new TQWidget(configBox));
  61. TQLabel *label = new TQLabel(i18n("History: "), configBox);
  62. label->setAlignment(AlignCenter);
  63. configLayout->addWidget(label);
  64. TQButtonGroup *buttonGroup = new TQButtonGroup(0);
  65. TQWidget *buttonGroupBox = new TQWidget(configBox);
  66. TQHBoxLayout *buttonGroupLayout = new TQHBoxLayout(buttonGroupBox);
  67. buttonGroupLayout->addStretch(0);
  68. configLayout->addWidget(buttonGroupBox);
  69. m_degrees = new TQRadioButton(i18n("&Degrees"), buttonGroupBox);
  70. buttonGroup->insert(m_degrees);
  71. buttonGroupLayout->addWidget(m_degrees);
  72. slotDegrees();
  73. connect(m_degrees, TQT_SIGNAL(clicked()), TQT_SLOT(slotDegrees()));
  74. m_radians = new TQRadioButton(i18n("&Radians"), buttonGroupBox);
  75. buttonGroup->insert(m_radians);
  76. buttonGroupLayout->addWidget(m_radians);
  77. connect(m_radians, TQT_SIGNAL(clicked()), TQT_SLOT(slotRadians()));
  78. m_history = new TQVBox(box);
  79. layout->addWidget(m_history);
  80. m_history->setSpacing(6);
  81. m_history->setMargin(0);
  82. m_result = new ResultListView(m_history);
  83. m_result->setSelectionMode(TQListView::NoSelection);
  84. m_result->setHScrollBarMode(ResultListView::AlwaysOff);
  85. connect(m_result, TQT_SIGNAL(signalEntrySelected(const TQString &)),
  86. TQT_SLOT(slotEntrySelected(const TQString &)));
  87. connect(m_result, TQT_SIGNAL(signalResultSelected(const TQString &)),
  88. TQT_SLOT(slotResultSelected(const TQString &)));
  89. m_history->setStretchFactor(m_result, 1);
  90. layout->setStretchFactor(m_history, 1);
  91. TQHBox *editBox = new TQHBox(box);
  92. layout->addWidget(editBox);
  93. editBox->setSpacing(6);
  94. m_edit = new Editor(editBox);
  95. m_edit->setFocus();
  96. editBox->setStretchFactor(m_edit, 1);
  97. KPushButton *evalButton = new KPushButton(i18n("&Evaluate"), editBox);
  98. connect(evalButton, TQT_SIGNAL(clicked()), TQT_SLOT(slotEvaluate()));
  99. connect(m_edit, TQT_SIGNAL(returnPressed()), TQT_SLOT(slotReturnPressed()));
  100. connect(m_edit, TQT_SIGNAL(textChanged()), TQT_SLOT(slotTextChanged()));
  101. m_listSplitter = new TQSplitter(Qt::Vertical, m_mainSplitter);
  102. m_fnList = new FunctionListView(m_listSplitter);
  103. m_fnList->addColumn("Functions");
  104. m_fnList->addColumn("Value");
  105. m_varList = new VariableListView(m_listSplitter);
  106. m_varList->addColumn("Variables");
  107. m_varList->addColumn("Value");
  108. connect(FunctionManager::instance(), TQT_SIGNAL(signalFunctionAdded(const TQString &)),
  109. this, TQT_SLOT(slotNewFunction(const TQString &)));
  110. connect(FunctionManager::instance(), TQT_SIGNAL(signalFunctionRemoved(const TQString &)),
  111. this, TQT_SLOT(slotRemoveFunction(const TQString &)));
  112. connect(ValueManager::instance(), TQT_SIGNAL(signalValueAdded(const TQString &, Abakus::number_t)),
  113. this, TQT_SLOT(slotNewValue(const TQString &, Abakus::number_t)));
  114. connect(ValueManager::instance(), TQT_SIGNAL(signalValueChanged(const TQString &, Abakus::number_t)),
  115. this, TQT_SLOT(slotChangeValue(const TQString &, Abakus::number_t)));
  116. connect(ValueManager::instance(), TQT_SIGNAL(signalValueRemoved(const TQString &)),
  117. this, TQT_SLOT(slotRemoveValue(const TQString &)));
  118. setupLayout();
  119. setCentralWidget(m_mainSplitter);
  120. #if KDE_IS_VERSION(3,4,89)
  121. setupGUI(TQSize(450, 400), Keys | StatusBar | Save | Create);
  122. #else
  123. setupGUI(Keys | StatusBar | Save | Create);
  124. #endif
  125. m_dcopInterface = new AbakusIface();
  126. }
  127. bool MainWindow::inRPNMode() const
  128. {
  129. return action<TDEToggleAction>("toggleExpressionMode")->isChecked();
  130. }
  131. bool MainWindow::eventFilter(TQObject *o, TQEvent *e)
  132. {
  133. return TDEMainWindow::eventFilter(o, e);
  134. }
  135. bool MainWindow::queryExit()
  136. {
  137. saveConfig();
  138. return TDEMainWindow::queryExit();
  139. }
  140. void MainWindow::contextMenuEvent(TQContextMenuEvent *e)
  141. {
  142. static TDEPopupMenu *popup = 0;
  143. if(!popup) {
  144. popup = new TDEPopupMenu(this);
  145. action("options_show_menubar")->plug(popup);
  146. }
  147. if(!action<TDEToggleAction>("options_show_menubar")->isChecked())
  148. popup->popup(e->globalPos());
  149. }
  150. void MainWindow::polish()
  151. {
  152. TDEMainWindow::polish();
  153. loadConfig();
  154. }
  155. void MainWindow::slotReturnPressed()
  156. {
  157. TQString text = m_edit->text();
  158. text.replace("\n", "");
  159. m_edit->appendHistory(text);
  160. // Item to insert after
  161. ResultListViewText *after = m_result->lastItem();
  162. // Expand $foo references.
  163. TQString str = interpolateExpression(text, after);
  164. TQString resultVal;
  165. ResultListViewText *item;
  166. if(str.isNull())
  167. return; // Error already has been posted
  168. m_insert = false; // Assume we failed
  169. if(inRPNMode()) {
  170. // We're in RPN mode.
  171. Abakus::number_t result = RPNParser::rpnParseString(str);
  172. if(!RPNParser::wasError()) {
  173. resultVal = result.toString();
  174. ValueManager::instance()->setValue("ans", result);
  175. m_insert = true;
  176. }
  177. else {
  178. m_insert = false;
  179. resultVal = i18n("Error: %1").arg(RPNParser::errorString());
  180. }
  181. // Skip creating list view items if in compact mode.
  182. if(!m_history->isShown()) {
  183. m_edit->setText(resultVal);
  184. TQTimer::singleShot(0, m_edit, TQT_SLOT(selectAll()));
  185. return;
  186. }
  187. item = new ResultListViewText(m_result, str, resultVal, after, false);
  188. }
  189. else {
  190. // Check to see if it's just a function name, if so, add (ans).
  191. if(FunctionManager::instance()->isFunction(str))
  192. str += " ans";
  193. // Add right parentheses as needed to balance out the expression.
  194. int parenLevel = getParenthesesLevel(str);
  195. for(int i = 0; i < parenLevel; ++i)
  196. str += ')';
  197. Abakus::number_t result = parseString(str.latin1());
  198. bool compact = !m_history->isShown();
  199. switch(Result::lastResult()->type()) {
  200. case Result::Value:
  201. resultVal = result.toString();
  202. ValueManager::instance()->setValue("ans", result);
  203. if(!compact)
  204. item = new ResultListViewText(m_result, str, result, after, false);
  205. m_insert = true;
  206. break;
  207. case Result::Null: // OK, no result to speak of
  208. resultVal = "OK";
  209. if(!compact)
  210. item = new ResultListViewText(m_result, str, resultVal, after, true);
  211. break;
  212. default:
  213. resultVal = Result::lastResult()->message();
  214. if(!compact)
  215. item = new ResultListViewText(m_result, str, resultVal, after, true);
  216. }
  217. // Skip creating list view items if in compact mode.
  218. if(compact) {
  219. m_edit->setText(resultVal);
  220. TQTimer::singleShot(0, m_edit, TQT_SLOT(selectAll()));
  221. return;
  222. }
  223. }
  224. m_edit->setText(text);
  225. m_result->setCurrentItem(item);
  226. m_result->ensureItemVisible(item);
  227. TQTimer::singleShot(0, m_edit, TQT_SLOT(selectAll()));
  228. }
  229. void MainWindow::slotTextChanged()
  230. {
  231. TQString str = m_edit->text();
  232. if(str.length() == 1 && m_insert) {
  233. m_insert = false;
  234. // Don't do anything if in RPN Mode.
  235. if(inRPNMode())
  236. return;
  237. if(str.find(TQRegExp("^[-+*/^]")) != -1) {
  238. m_edit->setText("ans " + str + " ");
  239. m_edit->moveCursor(TQTextEdit::MoveEnd, false);
  240. }
  241. }
  242. }
  243. void MainWindow::slotEvaluate()
  244. {
  245. slotReturnPressed();
  246. }
  247. void MainWindow::slotUpdateSize()
  248. {
  249. if(m_newSize != TQSize(0, 0))
  250. resize(m_newSize);
  251. else
  252. resize(width(), minimumSize().height());
  253. }
  254. void MainWindow::slotDegrees()
  255. {
  256. setTrigMode(Abakus::Degrees);
  257. m_degrees->setChecked(true);
  258. if(action("setDegreesMode"))
  259. action<TDEToggleAction>("setDegreesMode")->setChecked(true);
  260. }
  261. void MainWindow::slotRadians()
  262. {
  263. setTrigMode(Abakus::Radians);
  264. m_radians->setChecked(true);
  265. if(action("setRadiansMode"))
  266. action<TDEToggleAction>("setRadiansMode")->setChecked(true);
  267. }
  268. int MainWindow::getParenthesesLevel(const TQString &str)
  269. {
  270. int level = 0;
  271. for(unsigned i = 0; i < str.length(); ++i)
  272. if(str[i] == '(')
  273. ++level;
  274. else if(str[i] == ')')
  275. --level;
  276. return level;
  277. }
  278. void MainWindow::loadConfig()
  279. {
  280. {
  281. TDEConfigGroup config(TDEGlobal::config(), "Settings");
  282. TQString mode = config.readEntry("Trigonometric mode", "Degrees");
  283. if(mode == "Degrees") {
  284. setTrigMode(Abakus::Degrees);
  285. m_degrees->setChecked(true);
  286. }
  287. else {
  288. setTrigMode(Abakus::Radians);
  289. m_radians->setChecked(true);
  290. }
  291. bool useRPN = config.readBoolEntry("Use RPN Mode", false);
  292. action<TDEToggleAction>("toggleExpressionMode")->setChecked(useRPN);
  293. int precision = config.readNumEntry("Decimal Precision", -1);
  294. if(precision < -1 || precision > 75)
  295. precision = -1;
  296. Abakus::m_prec = precision;
  297. selectCorrectPrecisionAction();
  298. }
  299. {
  300. TDEConfigGroup config(TDEGlobal::config(), "Variables");
  301. TQStringList list = config.readListEntry("Saved Variables");
  302. for(TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it) {
  303. TQStringList values = TQStringList::split('=', *it);
  304. if(values.count() != 2) {
  305. kdWarning() << "Your configuration file has somehow been corrupted!\n";
  306. continue;
  307. }
  308. ValueManager::instance()->setValue(values[0], Abakus::number_t(values[1].latin1()));
  309. }
  310. }
  311. {
  312. TDEConfigGroup config(TDEGlobal::config(), "GUI");
  313. bool showHistory = config.readBoolEntry("ShowHistory", true);
  314. action<TDEToggleAction>("toggleHistoryList")->setChecked(showHistory);
  315. m_history->setShown(showHistory);
  316. bool showFunctions = config.readBoolEntry("ShowFunctions", true);
  317. action<TDEToggleAction>("toggleFunctionList")->setChecked(showFunctions);
  318. m_fnList->setShown(showFunctions);
  319. bool showVariables = config.readBoolEntry("ShowVariables", true);
  320. action<TDEToggleAction>("toggleVariableList")->setChecked(showVariables);
  321. m_varList->setShown(showVariables);
  322. bool compactMode = config.readBoolEntry("InCompactMode", false);
  323. compactMode = compactMode || !showHistory;
  324. action<TDEToggleAction>("toggleCompactMode")->setChecked(compactMode);
  325. if(compactMode)
  326. TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(slotToggleCompactMode()));
  327. }
  328. {
  329. TDEConfigGroup config(TDEGlobal::config(), "Functions");
  330. TQStringList fnList = config.readListEntry("FunctionList");
  331. for(TQStringList::ConstIterator it = fnList.begin(); it != fnList.end(); ++it)
  332. parseString((*it).ascii()); // Run the function definitions through the parser
  333. }
  334. populateListViews();
  335. }
  336. void MainWindow::saveConfig()
  337. {
  338. {
  339. TDEConfigGroup config(TDEGlobal::config(), "Settings");
  340. config.writeEntry("Trigonometric mode",
  341. trigMode() == Abakus::Degrees
  342. ? "Degrees"
  343. : "Radians");
  344. config.writeEntry("Use RPN Mode", inRPNMode());
  345. config.writeEntry("Decimal Precision", Abakus::m_prec);
  346. }
  347. {
  348. TDEConfigGroup config(TDEGlobal::config(), "Variables");
  349. TQStringList list;
  350. TQStringList values = ValueManager::instance()->valueNames();
  351. TQStringList::ConstIterator it = values.begin();
  352. // Set precision to max for most accuracy
  353. Abakus::m_prec = 75;
  354. for(; it != values.end(); ++it) {
  355. if(ValueManager::instance()->isValueReadOnly(*it))
  356. continue;
  357. list += TQString("%1=%2")
  358. .arg(*it)
  359. .arg(ValueManager::instance()->value(*it).toString());
  360. }
  361. config.writeEntry("Saved Variables", list);
  362. }
  363. {
  364. TDEConfigGroup config(TDEGlobal::config(), "GUI");
  365. bool inCompactMode = action<TDEToggleAction>("toggleCompactMode")->isChecked();
  366. config.writeEntry("InCompactMode", inCompactMode);
  367. if(!inCompactMode) {
  368. config.writeEntry("ShowHistory", m_history->isShown());
  369. config.writeEntry("ShowFunctions", m_fnList->isShown());
  370. config.writeEntry("ShowVariables", m_varList->isShown());
  371. }
  372. else {
  373. config.writeEntry("ShowHistory", m_wasHistoryShown);
  374. config.writeEntry("ShowFunctions", m_wasFnShown);
  375. config.writeEntry("ShowVariables", m_wasVarShown);
  376. }
  377. }
  378. {
  379. TDEConfigGroup config(TDEGlobal::config(), "Functions");
  380. FunctionManager *manager = FunctionManager::instance();
  381. TQStringList userFunctions = manager->functionList(FunctionManager::UserDefined);
  382. TQStringList saveList;
  383. for(TQStringList::ConstIterator it = userFunctions.begin(); it != userFunctions.end(); ++it) {
  384. UnaryFunction *fn = dynamic_cast<UnaryFunction *>(manager->function(*it)->userFn->fn);
  385. TQString var = manager->function(*it)->userFn->varName;
  386. TQString expr = fn->operand()->infixString();
  387. saveList += TQString("set %1(%2) = %3").arg(*it).arg(var).arg(expr);
  388. }
  389. config.writeEntry("FunctionList", saveList);
  390. }
  391. }
  392. void MainWindow::setupLayout()
  393. {
  394. TDEActionCollection *ac = actionCollection();
  395. KStdAction::quit(TQT_TQOBJECT(kapp), TQT_SLOT(quit()), ac);
  396. KStdAction::showMenubar(TQT_TQOBJECT(this), TQT_SLOT(slotToggleMenuBar()), ac);
  397. TDEToggleAction *ta = new TDEToggleAction(i18n("&Degrees"), SHIFT + ALT + Key_D, TQT_TQOBJECT(this), TQT_SLOT(slotDegrees()), ac, "setDegreesMode");
  398. ta->setExclusiveGroup("TrigMode");
  399. ta->setChecked(trigMode() == Abakus::Degrees);
  400. ta = new TDEToggleAction(i18n("&Radians"), SHIFT + ALT + Key_R, TQT_TQOBJECT(this), TQT_SLOT(slotRadians()), ac, "setRadiansMode");
  401. ta->setExclusiveGroup("TrigMode");
  402. ta->setChecked(trigMode() == Abakus::Radians);
  403. ta = new TDEToggleAction(i18n("Show &History List"), SHIFT + ALT + Key_H, TQT_TQOBJECT(this), TQT_SLOT(slotToggleHistoryList()), ac, "toggleHistoryList");
  404. ta->setChecked(true);
  405. ta = new TDEToggleAction(i18n("Show &Variables"), SHIFT + ALT + Key_V, TQT_TQOBJECT(this), TQT_SLOT(slotToggleVariableList()), ac, "toggleVariableList");
  406. ta->setChecked(true);
  407. ta = new TDEToggleAction(i18n("Show &Functions"), SHIFT + ALT + Key_F, TQT_TQOBJECT(this), TQT_SLOT(slotToggleFunctionList()), ac, "toggleFunctionList");
  408. ta->setChecked(true);
  409. ta = new TDEToggleAction(i18n("Activate &Compact Mode"), SHIFT + ALT + Key_C, TQT_TQOBJECT(this), TQT_SLOT(slotToggleCompactMode()), ac, "toggleCompactMode");
  410. ta->setChecked(false);
  411. ta = new TDEToggleAction(i18n("Use R&PN Mode"), SHIFT + ALT + Key_P, TQT_TQOBJECT(this), TQT_SLOT(slotToggleExpressionMode()), ac, "toggleExpressionMode");
  412. ta->setChecked(false);
  413. // Precision actions.
  414. ta = new TDEToggleAction(i18n("&Automatic Precision"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotPrecisionAuto()), ac, "precisionAuto");
  415. ta->setExclusiveGroup("Precision");
  416. ta->setChecked(true);
  417. ta = new TDEToggleAction(i18n("&3 Decimal Digits"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotPrecision3()), ac, "precision3");
  418. ta->setExclusiveGroup("Precision");
  419. ta->setChecked(false);
  420. ta = new TDEToggleAction(i18n("&8 Decimal Digits"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotPrecision8()), ac, "precision8");
  421. ta->setExclusiveGroup("Precision");
  422. ta->setChecked(false);
  423. ta = new TDEToggleAction(i18n("&15 Decimal Digits"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotPrecision15()), ac, "precision15");
  424. ta->setExclusiveGroup("Precision");
  425. ta->setChecked(false);
  426. ta = new TDEToggleAction(i18n("&50 Decimal Digits"), 0, TQT_TQOBJECT(this), TQT_SLOT(slotPrecision50()), ac, "precision50");
  427. ta->setExclusiveGroup("Precision");
  428. ta->setChecked(false);
  429. ta = new TDEToggleAction(i18n("C&ustom Precision..."), 0, TQT_TQOBJECT(this), TQT_SLOT(slotPrecisionCustom()), ac, "precisionCustom");
  430. ta->setExclusiveGroup("Precision");
  431. ta->setChecked(false);
  432. new TDEAction(i18n("Clear &History"), "editclear", SHIFT + ALT + Key_L, TQT_TQOBJECT(m_result), TQT_SLOT(clear()), ac, "clearHistory");
  433. new TDEAction(i18n("Select Editor"), "goto", Key_F6, TQT_TQOBJECT(m_edit), TQT_SLOT(setFocus()), ac, "select_edit");
  434. }
  435. void MainWindow::populateListViews()
  436. {
  437. TQStringList values = ValueManager::instance()->valueNames();
  438. Abakus::number_t value = ValueManager::instance()->value("pi");
  439. new ValueListViewItem(m_varList, "pi", value);
  440. value = ValueManager::instance()->value("e");
  441. new ValueListViewItem(m_varList, "e", value);
  442. }
  443. TDEAction *MainWindow::action(const char *key) const
  444. {
  445. return actionCollection()->action(key);
  446. }
  447. void MainWindow::slotEntrySelected(const TQString &text)
  448. {
  449. m_edit->setText(text);
  450. m_edit->moveCursor(TQTextEdit::MoveEnd, false);
  451. }
  452. void MainWindow::slotResultSelected(const TQString &text)
  453. {
  454. m_edit->insert(text);
  455. }
  456. void MainWindow::slotToggleMenuBar()
  457. {
  458. menuBar()->setShown(!menuBar()->isShown());
  459. }
  460. void MainWindow::slotToggleFunctionList()
  461. {
  462. bool show = action<TDEToggleAction>("toggleFunctionList")->isChecked();
  463. m_fnList->setShown(show);
  464. if(!m_history->isShown()) {
  465. m_history->setShown(true);
  466. action<TDEToggleAction>("toggleHistoryList")->setChecked(true);
  467. slotToggleHistoryList();
  468. }
  469. action<TDEToggleAction>("toggleCompactMode")->setChecked(false);
  470. }
  471. void MainWindow::slotToggleVariableList()
  472. {
  473. bool show = action<TDEToggleAction>("toggleVariableList")->isChecked();
  474. m_varList->setShown(show);
  475. if(!m_history->isShown()) {
  476. m_history->setShown(true);
  477. action<TDEToggleAction>("toggleHistoryList")->setChecked(true);
  478. slotToggleHistoryList();
  479. }
  480. action<TDEToggleAction>("toggleCompactMode")->setChecked(false);
  481. }
  482. void MainWindow::slotToggleHistoryList()
  483. {
  484. bool show = action<TDEToggleAction>("toggleHistoryList")->isChecked();
  485. m_history->setShown(show);
  486. action<TDEToggleAction>("toggleCompactMode")->setChecked(false);
  487. }
  488. void MainWindow::slotNewFunction(const TQString &name)
  489. {
  490. UserFunction *userFn = FunctionManager::instance()->function(name)->userFn;
  491. UnaryFunction *fn = dynamic_cast<UnaryFunction *>(userFn->fn);
  492. TQString fnName = TQString("%1(%2)").arg(name, userFn->varName);
  493. TQString expr = fn->operand()->infixString();
  494. new TDEListViewItem(m_fnList, fnName, expr);
  495. }
  496. void MainWindow::slotRemoveFunction(const TQString &name)
  497. {
  498. UserFunction *userFn = FunctionManager::instance()->function(name)->userFn;
  499. TQString fnName = TQString("%1(%2)").arg(name, userFn->varName);
  500. TQListViewItem *item = 0;
  501. while((item = m_fnList->findItem(fnName, 0)) != 0)
  502. delete item;
  503. }
  504. void MainWindow::slotNewValue(const TQString &name, Abakus::number_t value)
  505. {
  506. new ValueListViewItem(m_varList, name, value);
  507. }
  508. void MainWindow::slotChangeValue(const TQString &name, Abakus::number_t value)
  509. {
  510. ValueListViewItem *item = static_cast<ValueListViewItem *>(m_varList->findItem(name, 0));
  511. if(item)
  512. item->valueChanged(value);
  513. }
  514. void MainWindow::slotRemoveValue(const TQString &name)
  515. {
  516. delete m_varList->findItem(name, 0);
  517. }
  518. void MainWindow::slotToggleCompactMode()
  519. {
  520. if(action<TDEToggleAction>("toggleCompactMode")->isChecked()) {
  521. m_wasFnShown = m_fnList->isShown();
  522. m_wasVarShown = m_varList->isShown();
  523. m_wasHistoryShown = m_history->isShown();
  524. m_fnList->setShown(false);
  525. m_varList->setShown(false);
  526. m_history->setShown(false);
  527. action<TDEToggleAction>("toggleFunctionList")->setChecked(false);
  528. action<TDEToggleAction>("toggleVariableList")->setChecked(false);
  529. action<TDEToggleAction>("toggleHistoryList")->setChecked(false);
  530. m_oldSize = size();
  531. m_newSize = TQSize(0, 0);
  532. TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(slotUpdateSize()));
  533. }
  534. else {
  535. m_fnList->setShown(m_wasFnShown);
  536. m_varList->setShown(m_wasVarShown);
  537. m_history->setShown(m_wasHistoryShown);
  538. action<TDEToggleAction>("toggleFunctionList")->setChecked(m_wasFnShown);
  539. action<TDEToggleAction>("toggleVariableList")->setChecked(m_wasVarShown);
  540. action<TDEToggleAction>("toggleHistoryList")->setChecked(m_wasHistoryShown);
  541. m_newSize = m_oldSize;
  542. TQTimer::singleShot(0, TQT_TQOBJECT(this), TQT_SLOT(slotUpdateSize()));
  543. }
  544. }
  545. void MainWindow::slotToggleExpressionMode()
  546. {
  547. }
  548. TQString MainWindow::interpolateExpression(const TQString &text, ResultListViewText *after)
  549. {
  550. TQString str(text);
  551. TQRegExp stackRE("\\$\\d+");
  552. int pos;
  553. while((pos = stackRE.search(str)) != -1) {
  554. TQString stackStr = stackRE.cap();
  555. Abakus::number_t value;
  556. unsigned numPos = stackStr.mid(1).toUInt();
  557. if(!m_result->getStackValue(numPos, value)) {
  558. new ResultListViewText(m_result, text, i18n("Marker %1 isn't set").arg(stackStr), after, true);
  559. return TQString();
  560. }
  561. str.replace(pos, stackStr.length(), value.toString());
  562. }
  563. return str;
  564. }
  565. void MainWindow::slotPrecisionAuto()
  566. {
  567. Abakus::m_prec = -1;
  568. redrawResults();
  569. }
  570. void MainWindow::slotPrecision3()
  571. {
  572. Abakus::m_prec = 3;
  573. redrawResults();
  574. }
  575. void MainWindow::slotPrecision8()
  576. {
  577. Abakus::m_prec = 8;
  578. redrawResults();
  579. }
  580. void MainWindow::slotPrecision15()
  581. {
  582. Abakus::m_prec = 15;
  583. redrawResults();
  584. }
  585. void MainWindow::slotPrecision50()
  586. {
  587. Abakus::m_prec = 50;
  588. redrawResults();
  589. }
  590. void MainWindow::slotPrecisionCustom()
  591. {
  592. bool ok = false;
  593. int precision = KInputDialog::getInteger(i18n("Select number of decimal digits to display"),
  594. i18n("Decimal precision:"), Abakus::m_prec, 0, 75, 1, &ok, this);
  595. if(ok) {
  596. Abakus::m_prec = precision;
  597. redrawResults();
  598. }
  599. selectCorrectPrecisionAction();
  600. }
  601. void MainWindow::redrawResults()
  602. {
  603. TQListViewItemIterator it(m_result);
  604. while(it.current()) {
  605. static_cast<ResultListViewText *>(it.current())->precisionChanged();
  606. ++it;
  607. }
  608. it = TQListViewItemIterator (m_varList);
  609. while(it.current()) {
  610. static_cast<ValueListViewItem *>(it.current())->valueChanged();
  611. ++it;
  612. }
  613. // Because of the way we implemented the menu, it is possible to deselect
  614. // every possibility, so make sure we have at least one selected.
  615. selectCorrectPrecisionAction();
  616. }
  617. // This function selects the correct precision action based on the value of
  618. // Abakus::m_prec. Useful for loading settings, or for custom precision
  619. // selection.
  620. void MainWindow::selectCorrectPrecisionAction()
  621. {
  622. switch(Abakus::m_prec) {
  623. case 3:
  624. action<TDEToggleAction>("precision3")->setChecked(true);
  625. break;
  626. case 8:
  627. action<TDEToggleAction>("precision8")->setChecked(true);
  628. break;
  629. case 15:
  630. action<TDEToggleAction>("precision15")->setChecked(true);
  631. break;
  632. case 50:
  633. action<TDEToggleAction>("precision50")->setChecked(true);
  634. break;
  635. case -1:
  636. action<TDEToggleAction>("precisionAuto")->setChecked(true);
  637. break;
  638. default:
  639. action<TDEToggleAction>("precisionCustom")->setChecked(true);
  640. }
  641. }
  642. #include "mainwindow.moc"
  643. // vim: set et ts=8 sw=4: