PageRenderTime 122ms CodeModel.GetById 39ms RepoModel.GetById 0ms app.codeStats 2ms

/qalculate-kde-0.9.7/src/kqalculate.cpp

#
C++ | 6676 lines | 6122 code | 512 blank | 42 comment | 1344 complexity | 17355f2590d00cf9a7d9cb719f846222 MD5 | raw file
Possible License(s): GPL-2.0
  1. /***************************************************************************
  2. * Copyright (C) 2005-2007 by Niklas Knutsson *
  3. * nq@altern.org *
  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 *
  17. * Free Software Foundation, Inc., *
  18. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  19. ***************************************************************************/
  20. #ifdef HAVE_CONFIG_H
  21. # include <config.h>
  22. #endif
  23. #include <kdialog.h>
  24. #include <klocale.h>
  25. #include "kqalculate.h"
  26. #include "qalculateinsertfunctiondialog.h"
  27. #include "qalculate_kde_utils.h"
  28. #include "preferences.h"
  29. #include "qalculatepreferencesdialog.h"
  30. #include "qalculateimportcsvdialog.h"
  31. #include "qalculateexportcsvdialog.h"
  32. #include "qalculateexpressionedit.h"
  33. #include "qalculateprecisiondialog.h"
  34. #include "qalculatedecimalsdialog.h"
  35. #include "qalculateeditvariabledialog.h"
  36. #include "qalculateeditmatrixvectordialog.h"
  37. #include "qalculateeditunitdialog.h"
  38. #include "qalculateeditfunctiondialog.h"
  39. #include "qalculateeditdatasetdialog.h"
  40. #include "qalculateeditunknownvariabledialog.h"
  41. #include "qalculatevariablesdialog.h"
  42. #include "qalculatefunctionsdialog.h"
  43. #include "qalculateunitsdialog.h"
  44. #include "qalculatedatasetsdialog.h"
  45. #include "qalculateconvertunitsdialog.h"
  46. #include "qalculateconvertnumberbasesdialog.h"
  47. #include "qalculateperiodictabledialog.h"
  48. #include "qalculateplotdialog.h"
  49. #include "qalculatesetbasedialog.h"
  50. #include "qalculateinsertmatrixvectordialog.h"
  51. #include <kwin.h>
  52. #include <kglobalsettings.h>
  53. #include <kuniqueapplication.h>
  54. #include <kstringhandler.h>
  55. #include <qtable.h>
  56. #include <kseparator.h>
  57. #include <kiconloader.h>
  58. #include <qframe.h>
  59. #include <qvariant.h>
  60. #include <qtooltip.h>
  61. #include <qwhatsthis.h>
  62. #include <qclipboard.h>
  63. #include <qstylesheet.h>
  64. #include <kcompletion.h>
  65. #include <klineedit.h>
  66. #include <qlabel.h>
  67. #include <kmessagebox.h>
  68. #include <qpixmap.h>
  69. #include <qpicture.h>
  70. #include <qpainter.h>
  71. #include <qfontmetrics.h>
  72. #include <sys/stat.h>
  73. #include <unistd.h>
  74. #include <time.h>
  75. #include <math.h>
  76. #include <dirent.h>
  77. #include <pthread.h>
  78. #include <qsimplerichtext.h>
  79. #include <qstatusbar.h>
  80. #include <qwidgetstack.h>
  81. #include <ktextbrowser.h>
  82. #include <kpushbutton.h>
  83. #include "qalculateresultdisplay.h"
  84. #include <qbitmap.h>
  85. #include <qscrollview.h>
  86. #include <qobject.h>
  87. #include <kapplication.h>
  88. #include <kaction.h>
  89. #include <qspinbox.h>
  90. #include <kprogress.h>
  91. #include <kpopupmenu.h>
  92. #include <kmenubar.h>
  93. #include <qlayout.h>
  94. #include <qtimer.h>
  95. #include <kcompletionbox.h>
  96. #include <qstringlist.h>
  97. #include <qcombobox.h>
  98. #include <ksystemtray.h>
  99. #if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR > 1
  100. #include <kactionclasses.h>
  101. #endif
  102. #if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4
  103. #include <kaccelmanager.h>
  104. #endif
  105. #include <qbuttongroup.h>
  106. #include <qvbuttongroup.h>
  107. #include <qradiobutton.h>
  108. #include <qgrid.h>
  109. #include <kfiledialog.h>
  110. #include <qimage.h>
  111. #include <kaccel.h>
  112. #include <kio/netaccess.h>
  113. #if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 2
  114. #include <kinputdialog.h>
  115. #endif
  116. #include <kdeversion.h>
  117. #include <qstyle.h>
  118. #include <kglobalaccel.h>
  119. #include <kkeydialog.h>
  120. #include <kkeybutton.h>
  121. #include <kcombobox.h>
  122. MathStructure *mstruct, *matrix_mstruct, *parsed_mstruct, *parsed_tostruct;
  123. QString result_text, result_history_text, parsed_text;
  124. QWidget *expressionWidget, *resultWidget, *statusWidget_l;
  125. QWidget *topWidget;
  126. KQalculate *mainWin = 0;
  127. bool prev_result_approx;
  128. extern bool close_to_systray;
  129. extern bool display_expression_status;
  130. extern QColor status_error_color;
  131. extern QColor status_warning_color;
  132. extern int use_icon_buttons;
  133. extern bool enable_expression_completion;
  134. extern QString initial_history;
  135. extern tree_struct function_cats, unit_cats, variable_cats;
  136. extern vector<void*> ia_units, ia_variables, ia_functions;
  137. extern vector<MathFunction*> recent_functions;
  138. extern vector<Variable*> recent_variables;
  139. extern vector<Unit*> recent_units;
  140. vector<MathStructure> result_parts;
  141. KnownVariable *vans[5];
  142. int vans_id_start[5];
  143. int vans_id_end[5];
  144. extern PrintOptions printops;
  145. extern EvaluationOptions evalops;
  146. extern bool rpn_mode, rpn_keypad_only;
  147. extern bool save_mode_on_exit, save_defs_on_exit;
  148. extern bool canplot;
  149. extern bool use_custom_result_font, use_custom_expression_font, use_custom_status_font;
  150. extern QString custom_result_font, custom_expression_font, custom_status_font;
  151. extern QTimer *error_timer;
  152. extern QStringList expression_history;
  153. bool expression_has_changed, expression_has_changed2, had_errors_before, had_warnings_before, block_result_update;
  154. FILE *view_pipe_r, *view_pipe_w, *command_pipe_r, *command_pipe_w;
  155. pthread_t view_thread, command_thread;
  156. pthread_attr_t view_thread_attr, command_thread_attr;
  157. bool b_busy, command_thread_started;
  158. int saved_divisionline_height = 0;
  159. uint initial_result_index = 0;
  160. extern bool show_keypad, show_history, show_stack;
  161. extern vector<mode_struct> modes;
  162. extern QValueVector<QString> inhistory;
  163. extern QValueVector<int> inhistory_type;
  164. extern QValueVector<int> inhistory_id;
  165. extern int inhistory_current_id;
  166. int initial_inhistory_index = 0;
  167. const MathStructure *KQalculate::getResultPart(int i) {
  168. if(i < 1 || (size_t) i > result_parts.size()) return NULL;
  169. return &result_parts[(size_t) i - 1];
  170. }
  171. #if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
  172. #include <kiconloader.h>
  173. #include <kconfig.h>
  174. QPixmap loadSystrayIcon(const QString &icon) {
  175. KConfig *appCfg = kapp->config();
  176. KConfigGroupSaver configSaver(appCfg, "System Tray");
  177. int iconWidth = appCfg->readNumEntry("systrayIconWidth", 22);
  178. return KGlobal::instance()->iconLoader()->loadIcon(icon, KIcon::Panel, iconWidth);
  179. }
  180. #endif
  181. #if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 3
  182. #define ICON_SIZE_SMALL_MEDIUM KIcon::SizeSmallMedium
  183. #else
  184. #define ICON_SIZE_SMALL_MEDIUM 22
  185. #endif
  186. ModeObject::ModeObject(int mode) : i_mode(mode) {}
  187. void ModeObject::loadMode() {
  188. mainWin->loadMode(i_mode);
  189. }
  190. KQalculate::KQalculate(KUniqueApplication *parent, const char* name, WFlags fl) : KMainWindow(0, name, fl) {
  191. if(!name) setName("kqalculate");
  192. m_parent = parent;
  193. vans_id_start[0] = -1;
  194. vans_id_end[0] = -1;
  195. vans_id_start[1] = -1;
  196. vans_id_end[1] = -1;
  197. vans_id_start[2] = -1;
  198. vans_id_end[2] = -1;
  199. vans_id_start[3] = -1;
  200. vans_id_end[3] = -1;
  201. vans_id_start[4] = -1;
  202. vans_id_end[4] = -1;
  203. QStyleSheet::setDefaultSheet(new QalculateStyleSheet());
  204. insert_matrix_dialog = NULL;
  205. preferences_dialog = NULL;
  206. precisionDialog = NULL;
  207. decimalsDialog = NULL;
  208. variable_edit_dialog = NULL;
  209. store_dialog = NULL;
  210. matrix_edit_dialog = NULL;
  211. import_csv_dialog = NULL;
  212. export_csv_dialog = NULL;
  213. unit_edit_dialog = NULL;
  214. function_edit_dialog = NULL;
  215. dataset_edit_dialog = NULL;
  216. unknown_edit_dialog = NULL;
  217. variables_dialog = NULL;
  218. functions_dialog = NULL;
  219. units_dialog = NULL;
  220. datasets_dialog = NULL;
  221. convert_to_unit_expression_dialog = NULL;
  222. convert_number_bases_dialog = NULL;
  223. periodic_table_dialog = NULL;
  224. plot_dialog = NULL;
  225. set_base_dialog = NULL;
  226. prev_result_approx = false;
  227. expression_has_changed = false;
  228. expression_has_changed2 = false;
  229. had_errors_before = false;
  230. had_warnings_before = false;
  231. block_result_update = false;
  232. history_height = 0;
  233. trayicon = NULL;
  234. ActionHideSystemTrayIcon = new KAction(i18n("Remove from System Tray"), "hidesystemtrayicon", 0, this, SLOT(hideSystemTrayIcon()), actionCollection(), "hide_system_tray_icon");
  235. ActionHide = new KAction(i18n("Hide"), "hide", 0, this, SLOT(hide()), actionCollection(), "hide");
  236. showSystemTrayIcon(close_to_systray);
  237. setCentralWidget(new QWidget(this));
  238. QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget(), 11, 6);
  239. mainLayout->setResizeMode(QLayout::Minimum);
  240. QHBoxLayout *topLayout = new QHBoxLayout(0, 0, 6);
  241. bool use_button_pixmaps = false;
  242. if(use_icon_buttons > 0) {
  243. use_button_pixmaps = true;
  244. } else if(use_icon_buttons < 0) {
  245. KConfig config("kdeglobals", true, false);
  246. config.setGroup("KDE");
  247. use_button_pixmaps = config.readBoolEntry("ShowIconsOnPushButtons", false);
  248. }
  249. if(use_button_pixmaps) leftButtonsLayout = new QVBoxLayout(0, 0, 3);
  250. else leftButtonsLayout = new QVBoxLayout(0, 0, 6);
  251. if(use_button_pixmaps) executeButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("exec", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", centralWidget());
  252. else if(rpn_mode) executeButton = new QalculateButton(i18n("Enter"), centralWidget());
  253. else executeButton = new QalculateButton(i18n("="), centralWidget());
  254. executeButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
  255. if(rpn_mode) QToolTip::add(executeButton, i18n("Calculate expression and add to stack"));
  256. else QToolTip::add(executeButton, i18n("Calculate expression"));
  257. leftButtonsLayout->addWidget(executeButton);
  258. leftButtonsSeparator = new KSeparator(Qt::Horizontal, centralWidget());
  259. leftButtonsLayout->addWidget(leftButtonsSeparator);
  260. if(use_button_pixmaps) leftButtonsSeparator->hide();
  261. if(use_button_pixmaps) storeButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("filesaveas", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", centralWidget());
  262. else storeButton = new QalculateButton(i18n("Store"), centralWidget());
  263. storeButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
  264. QToolTip::add(storeButton, i18n("Store result as variable"));
  265. leftButtonsLayout->addWidget(storeButton);
  266. if(use_button_pixmaps) convertButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("qalculate_convert", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", centralWidget());
  267. else convertButton = new QalculateButton(i18n("Convert"), centralWidget());
  268. convertButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
  269. QToolTip::add(convertButton, i18n("Convert units in result"));
  270. leftButtonsLayout->addWidget(convertButton);
  271. leftButtonsLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum));
  272. QVBoxLayout *expressionLayout = new QVBoxLayout(0, 0, 0);
  273. expressionEdit = new QalculateExpressionEdit(true, centralWidget());
  274. expressionLayout->addWidget(expressionEdit);
  275. expressionEdit->setFocus();
  276. expressionEdit->expression_history = expression_history;
  277. if(!enable_expression_completion) expressionEdit->disableCompletion();
  278. QToolTip::add(expressionEdit, i18n("Enter expression here"));
  279. QHBoxLayout *statusLayout = new QHBoxLayout(0, 0, 6);
  280. statusLabel_l = new QalculateParseLabel(centralWidget());
  281. statusLabel_l->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
  282. statusLabel_l->setLineWidth(0);
  283. statusLabel_l->setMargin(0);
  284. statusLabel_l->setAlignment(int(QLabel::AlignTop | QLabel::AlignLeft));
  285. if(!display_expression_status) statusLabel_l->hide();
  286. statusLayout->addWidget(statusLabel_l);
  287. statusLabel_r = new QLabel(i18n("status"), centralWidget());
  288. statusLabel_r->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum, false);
  289. statusLabel_r->setLineWidth(0);
  290. statusLabel_r->setMargin(0);
  291. statusLabel_r->setTextFormat(Qt::RichText);
  292. statusLabel_r->setAlignment(int(QLabel::AlignTop | QLabel::AlignRight));
  293. statusLayout->addWidget(statusLabel_r);
  294. expressionLayout->addLayout(statusLayout);
  295. resultLabel = new QalculateResultDisplay(centralWidget());
  296. resultLabel->setRightMargin(10);
  297. expressionLayout->addWidget(resultLabel);
  298. topLayout->addLayout(expressionLayout);
  299. topLayout->addLayout(leftButtonsLayout);
  300. mainLayout->addLayout(topLayout);
  301. resultLabel->setWordWrap(QTextEdit::WidgetWidth);
  302. resultLabel->setMargin(0);
  303. bottomLine = new KSeparator(Qt::Horizontal, centralWidget());
  304. mainLayout->addWidget(bottomLine);
  305. mainStack = new QWidgetStack(centralWidget());
  306. mainStack->setEnabled(true);
  307. mainStack->setSizePolicy(QSizePolicy((QSizePolicy::SizeType) 5, (QSizePolicy::SizeType) 7, 0, 0, mainStack->sizePolicy().hasHeightForWidth()));
  308. keypadPage = new QWidget(mainStack);
  309. QVBoxLayout *keypadPageLayout = new QVBoxLayout(keypadPage, 0, 12);
  310. keypadPageLayout->addWidget(new KSeparator(Qt::Horizontal, keypadPage));
  311. QHBoxLayout *keypadTopLayout = new QHBoxLayout(0, 0, 6);
  312. kpExact = new QalculateButton(i18n("Exact"), keypadPage);
  313. QToolTip::add(kpExact, i18n("Toggle exact mode"));
  314. kpExact->setToggleButton(true);
  315. keypadTopLayout->addWidget(kpExact);
  316. kpFraction = new QalculateButton(i18n("Fraction"), keypadPage);
  317. QToolTip::add(kpFraction, i18n("Toggle fractional display"));
  318. kpFraction->setToggleButton(true);
  319. keypadTopLayout->addWidget(kpFraction);
  320. kpNumericCombo = new QComboBox(true, keypadPage);
  321. QToolTip::add(kpNumericCombo, i18n("Numerical display"));
  322. kpNumericCombo->setEditable(false);
  323. keypadTopLayout->addWidget(kpNumericCombo);
  324. kpNumericCombo->insertItem(i18n("Normal"));
  325. kpNumericCombo->insertItem(i18n("Engineering"));
  326. kpNumericCombo->insertItem(i18n("Scientific"));
  327. kpNumericCombo->insertItem(i18n("Pure"));
  328. kpNumericCombo->insertItem(i18n("Simple"));
  329. kpBaseCombo = new QComboBox(true, keypadPage);
  330. QToolTip::add(kpBaseCombo, i18n("Base in result"));
  331. kpBaseCombo->setEditable(false);
  332. keypadTopLayout->addWidget(kpBaseCombo);
  333. keypadPageLayout->addLayout(keypadTopLayout);
  334. kpBaseCombo->insertItem(i18n("Binary"));
  335. kpBaseCombo->insertItem(i18n("Octal"));
  336. kpBaseCombo->insertItem(i18n("Decimal"));
  337. kpBaseCombo->insertItem(i18n("Hexadecimal"));
  338. kpBaseCombo->insertItem(i18n("Sexagesimal"));
  339. kpBaseCombo->insertItem(i18n("Time Format"));
  340. kpBaseCombo->insertItem(i18n("Roman"));
  341. kpBaseCombo->insertItem(i18n("Other..."));
  342. QHBoxLayout *keypadBottomLayout = new QHBoxLayout(0, 0, 24);
  343. QGridLayout *keypadFunctionsLayout = new QGridLayout(0, 5, 3, 0, 6);
  344. functionsButton = new QalculateButton(i18n("f(x)"), keypadPage);
  345. QFont fb_font(functionsButton->font());
  346. fb_font.setItalic(true);
  347. functionsButton->setFont(fb_font);
  348. QToolTip::add(functionsButton, i18n("Open functions manager"));
  349. keypadFunctionsLayout->addWidget(functionsButton, 0, 0);
  350. kpSqrt = new QalculateButton(i18n("sqrt"), keypadPage);
  351. QToolTip::add(kpSqrt, i18n("Square root"));
  352. keypadFunctionsLayout->addWidget(kpSqrt, 1, 0);
  353. kpRaise = new QalculateButton(keypadPage);
  354. kpRaise->setMarkup(i18n("x<sup>y</sup>"));
  355. QToolTip::add(kpRaise, i18n("Raise (Ctrl+*)"));
  356. keypadFunctionsLayout->addWidget(kpRaise, 0, 1);
  357. kpSquare = new QalculateButton(keypadPage);
  358. kpSquare->setMarkup(i18n("x<sup>2</sup>"));
  359. QToolTip::add(kpSquare, i18n("Square"));
  360. keypadFunctionsLayout->addWidget(kpSquare, 0, 2);
  361. kpLog = new QalculateButton(i18n("log"), keypadPage);
  362. QToolTip::add(kpLog, i18n("Base-10 logarithm"));
  363. keypadFunctionsLayout->addWidget(kpLog, 1, 1);
  364. kpLn = new QalculateButton(i18n("ln"), keypadPage);
  365. QToolTip::add(kpLn, i18n("Natural logarithm"));
  366. keypadFunctionsLayout->addWidget(kpLn, 1, 2);
  367. kpFactorial = new QalculateButton(i18n("x!"), keypadPage);
  368. QToolTip::add(kpFactorial, i18n("Factorial"));
  369. keypadFunctionsLayout->addWidget(kpFactorial, 2, 0);
  370. kpCos = new QalculateButton(i18n("cos"), keypadPage);
  371. QToolTip::add(kpCos, i18n("Cosine"));
  372. keypadFunctionsLayout->addWidget(kpCos, 2, 1);
  373. kpTan = new QalculateButton(i18n("tan"), keypadPage);
  374. QToolTip::add(kpTan, i18n("Tangent"));
  375. keypadFunctionsLayout->addWidget(kpTan, 2, 2);
  376. kpHyp = new QalculateButton(i18n("hyp"), keypadPage);
  377. QToolTip::add(kpHyp, i18n("Toggle hyperbolic functions"));
  378. kpHyp->setToggleButton(true);
  379. keypadFunctionsLayout->addWidget(kpHyp, 3, 0);
  380. kpInv = new QalculateButton(i18n("inv"), keypadPage);
  381. QToolTip::add(kpInv, i18n("Toggle inverse functions"));
  382. kpInv->setToggleButton(true);
  383. keypadFunctionsLayout->addWidget(kpInv, 3, 1);
  384. kpSin = new QalculateButton(i18n("sin"), keypadPage);
  385. QToolTip::add(kpSin, i18n("Sine"));
  386. keypadFunctionsLayout->addWidget(kpSin, 3, 2);
  387. QHBoxLayout *keypadAngleLayout = new QHBoxLayout(0, 0, 6);
  388. kpAngleGroup = new QButtonGroup();
  389. kpAngleGroup->setExclusive(true);
  390. kpDegreesButton = new QRadioButton(i18n("Deg"), keypadPage);
  391. QToolTip::add(kpDegreesButton, i18n("Angle Unit: Degrees"));
  392. kpAngleGroup->insert(kpDegreesButton, 0);
  393. keypadAngleLayout->addWidget(kpDegreesButton);
  394. kpRadiansButton = new QRadioButton(i18n("Rad"), keypadPage);
  395. QToolTip::add(kpRadiansButton, i18n("Angle Unit: Radians"));
  396. kpAngleGroup->insert(kpRadiansButton, 1);
  397. keypadAngleLayout->addWidget(kpRadiansButton);
  398. kpGradiansButton = new QRadioButton(i18n("Gra"), keypadPage);
  399. QToolTip::add(kpGradiansButton, i18n("Angle Unit: Gradians"));
  400. kpAngleGroup->insert(kpGradiansButton, 2);
  401. keypadAngleLayout->addWidget(kpGradiansButton);
  402. kpNoAngleUnitButton = new QRadioButton(i18n("None"), keypadPage);
  403. kpAngleGroup->insert(kpNoAngleUnitButton, 3);
  404. keypadAngleLayout->addWidget(kpNoAngleUnitButton);
  405. kpNoAngleUnitButton->hide();
  406. keypadAngleLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum));
  407. keypadFunctionsLayout->addMultiCellLayout(keypadAngleLayout, 4, 4, 0, 2);
  408. #if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4
  409. KAcceleratorManager::setNoAccel(kpDegreesButton);
  410. KAcceleratorManager::setNoAccel(kpRadiansButton);
  411. KAcceleratorManager::setNoAccel(kpGradiansButton);
  412. KAcceleratorManager::setNoAccel(kpNoAngleUnitButton);
  413. #endif
  414. keypadBottomLayout->addLayout(keypadFunctionsLayout);
  415. QGridLayout *keypadBasicsLayout = new QGridLayout(0, 1, 1, 0, 6);
  416. kp7 = new QalculateButton(i18n("7"), keypadPage);
  417. keypadBasicsLayout->addWidget(kp7, 0, 0);
  418. kp8 = new QalculateButton(i18n("8"), keypadPage);
  419. keypadBasicsLayout->addWidget(kp8, 0, 1);
  420. kp9 = new QalculateButton(i18n("9"), keypadPage);
  421. keypadBasicsLayout->addWidget(kp9, 0, 2);
  422. kp4 = new QalculateButton(i18n("4"), keypadPage);
  423. keypadBasicsLayout->addWidget(kp4, 1, 0);
  424. kp5 = new QalculateButton(i18n("5"), keypadPage);
  425. keypadBasicsLayout->addWidget(kp5, 1, 1);
  426. kp6 = new QalculateButton(i18n("6"), keypadPage);
  427. keypadBasicsLayout->addWidget(kp6, 1, 2);
  428. kp1 = new QalculateButton(i18n("1"), keypadPage);
  429. keypadBasicsLayout->addWidget(kp1, 2, 0);
  430. kp2 = new QalculateButton(i18n("2"), keypadPage);
  431. keypadBasicsLayout->addWidget(kp2, 2, 1);
  432. kp3 = new QalculateButton(i18n("3"), keypadPage);
  433. keypadBasicsLayout->addWidget(kp3, 2, 2);
  434. kp0 = new QalculateButton(i18n("0"), keypadPage);
  435. keypadBasicsLayout->addWidget(kp0, 3, 0);
  436. kpDot = new QalculateButton(".", keypadPage);
  437. QToolTip::add(kpDot, i18n("Decimal point"));
  438. keypadBasicsLayout->addWidget(kpDot, 3, 1);
  439. kpExp = new QalculateButton(i18n("EXP"), keypadPage);
  440. QToolTip::add(kpExp, i18n("10^x (Ctrl+Shift+E)"));
  441. keypadBasicsLayout->addWidget(kpExp, 3, 2);
  442. kpDel = new QalculateButton(i18n("Del"), keypadPage);
  443. QToolTip::add(kpDel, i18n("Delete"));
  444. keypadBasicsLayout->addWidget(kpDel, 0, 3);
  445. kpClear = new QalculateButton(i18n("AC"), keypadPage);
  446. QToolTip::add(kpClear, i18n("Clear"));
  447. keypadBasicsLayout->addWidget(kpClear, 0, 4);
  448. kpTimes = new QalculateButton("*", keypadPage);
  449. QToolTip::add(kpTimes, i18n("Multiply"));
  450. keypadBasicsLayout->addWidget(kpTimes, 1, 3);
  451. kpDivision = new QalculateButton("/", keypadPage);
  452. QToolTip::add(kpDivision, i18n("Divide"));
  453. keypadBasicsLayout->addWidget(kpDivision, 1, 4);
  454. kpPlus = new QalculateButton("+", keypadPage);
  455. QToolTip::add(kpPlus, i18n("Add"));
  456. keypadBasicsLayout->addWidget(kpPlus, 2, 3);
  457. kpMinus = new QalculateButton("-", keypadPage);
  458. QToolTip::add(kpMinus, i18n("Subtract"));
  459. keypadBasicsLayout->addWidget(kpMinus, 2, 4);
  460. kpAns = new QalculateButton(i18n("Ans"), keypadPage);
  461. QToolTip::add(kpAns, i18n("Previous result"));
  462. keypadBasicsLayout->addWidget(kpAns, 3, 3);
  463. if(rpn_mode) kpEquals = new QalculateButton(i18n("Ent"), keypadPage);
  464. else kpEquals = new QalculateButton(i18n("="), keypadPage);
  465. if(rpn_mode) QToolTip::add(kpEquals, i18n("Calculate expression and add to stack"));
  466. else QToolTip::add(kpEquals, i18n("Calculate expression"));
  467. keypadBasicsLayout->addWidget(kpEquals, 3, 4);
  468. keypadBottomLayout->addLayout(keypadBasicsLayout);
  469. keypadPageLayout->addLayout(keypadBottomLayout);
  470. keypadPageLayout->addWidget(new KSeparator(Qt::Horizontal, keypadPage));
  471. mainStack->addWidget(keypadPage, 0);
  472. historyPage = new QWidget(mainStack, "historyPage");
  473. QVBoxLayout *historyPageLayout = new QVBoxLayout(historyPage, 0, 0);
  474. historyBrowser = new QalculateHistoryBrowser(historyPage, "historyBrowser");
  475. historyBrowser->setTextFormat(KTextBrowser::RichText);
  476. historyBrowser->setWordWrap(KTextBrowser::NoWrap);
  477. historyPageLayout->addWidget(historyBrowser);
  478. mainStack->addWidget(historyPage, 1);
  479. stackPage = new QWidget(mainStack, "stackPage");
  480. QHBoxLayout *stackPageLayout = new QHBoxLayout(stackPage, 0, 6);
  481. stackList = new QalculateRPNStackListView(stackPage, "stackList");
  482. stackList->addColumn(i18n("Index"));
  483. stackList->addColumn(i18n("Value"));
  484. stackList->setColumnAlignment(0, Qt::AlignCenter);
  485. stackList->setColumnAlignment(1, Qt::AlignRight);
  486. stackList->setFullWidth(true);
  487. stackList->setResizeMode(QListView::LastColumn);
  488. stackList->setSelectionMode(QListView::Single);
  489. stackList->setAllColumnsShowFocus(true);
  490. stackList->setRootIsDecorated(false);
  491. stackList->setItemsMovable(true);
  492. stackList->setDragEnabled(true);
  493. stackList->setAcceptDrops(true);
  494. stackList->setSorting(-1);
  495. stackList->setItemsRenameable(true);
  496. stackList->setRenameable(1, true);
  497. stackList->setRenameable(0, false);
  498. stackPageLayout->addWidget(stackList);
  499. if(use_button_pixmaps) stackPageButtonsLayout = new QVBoxLayout(stackPageLayout, 3);
  500. else stackPageButtonsLayout = new QVBoxLayout(stackPageLayout, 6);
  501. if(use_button_pixmaps) registerUpButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("up", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage);
  502. else registerUpButton = new QalculateButton(i18n("Up"), stackPage);
  503. QToolTip::add(registerUpButton, i18n("Move selected register up"));
  504. registerUpButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
  505. stackPageButtonsLayout->addWidget(registerUpButton);
  506. if(use_button_pixmaps) registerDownButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("down", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage);
  507. else registerDownButton = new QalculateButton(i18n("Down"), stackPage);
  508. QToolTip::add(registerDownButton, i18n("Move selected register down"));
  509. registerDownButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
  510. stackPageButtonsLayout->addWidget(registerDownButton);
  511. if(use_button_pixmaps) editRegisterButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("edit", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage);
  512. else editRegisterButton = new QalculateButton(i18n("Edit"), stackPage);
  513. QToolTip::add(editRegisterButton, i18n("Edit value of selected register"));
  514. editRegisterButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
  515. stackPageButtonsLayout->addWidget(editRegisterButton);
  516. if(use_button_pixmaps) deleteRegisterButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("editdelete", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage);
  517. else deleteRegisterButton = new QalculateButton(i18n("Delete"), stackPage);
  518. QToolTip::add(deleteRegisterButton, i18n("Delete selected register"));
  519. deleteRegisterButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
  520. stackPageButtonsLayout->addWidget(deleteRegisterButton);
  521. if(use_button_pixmaps) clearStackButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("view_remove", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage);
  522. else clearStackButton = new QalculateButton(i18n("Clear"), stackPage);
  523. QToolTip::add(clearStackButton, i18n("Clear the RPN stack"));
  524. clearStackButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
  525. registerUpButton->setEnabled(false);
  526. registerDownButton->setEnabled(false);
  527. editRegisterButton->setEnabled(false);
  528. deleteRegisterButton->setEnabled(false);
  529. clearStackButton->setEnabled(false);
  530. stackPageButtonsLayout->addWidget(clearStackButton);
  531. stackPageButtonsLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding));
  532. mainStack->addWidget(stackPage, 2);
  533. updateButtonWidths();
  534. mainLayout->addWidget(mainStack);
  535. QHBoxLayout *bottomLayout = new QHBoxLayout(0, 0, 6);
  536. keypadButton = new QPushButton(i18n("Keypad"), centralWidget());
  537. QToolTip::add(keypadButton, i18n("Show/hide keypad"));
  538. keypadButton->setToggleButton(true);
  539. bottomLayout->addWidget(keypadButton);
  540. historyButton = new QPushButton(i18n("History"), centralWidget());
  541. QToolTip::add(historyButton, i18n("Show/hide history"));
  542. historyButton->setToggleButton(true);
  543. bottomLayout->addWidget(historyButton);
  544. stackButton = new QPushButton(i18n("RPN Stack"), centralWidget());
  545. QToolTip::add(stackButton, i18n("Show/hide RPN stack"));
  546. stackButton->setToggleButton(true);
  547. bottomLayout->addWidget(stackButton);
  548. if(!rpn_mode) stackButton->hide();
  549. bottomLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum));
  550. mainLayout->addLayout(bottomLayout);
  551. connect(stackList, SIGNAL(selectionChanged()), this, SLOT(registerSelected()));
  552. connect(stackList, SIGNAL(itemRenamed(QListViewItem*)), this, SLOT(stackRegisterSet(QListViewItem*)));
  553. connect(stackList, SIGNAL(moved()), this, SLOT(stackRegisterMoved()));
  554. connect(stackList, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)), this, SLOT(popupStackMenu(KListView*, QListViewItem*, const QPoint&)));
  555. connect(registerUpButton, SIGNAL(clicked()), this, SLOT(registerUp()));
  556. connect(registerDownButton, SIGNAL(clicked()), this, SLOT(registerDown()));
  557. connect(editRegisterButton, SIGNAL(clicked()), this, SLOT(editRegister()));
  558. connect(deleteRegisterButton, SIGNAL(clicked()), this, SLOT(deleteRegister()));
  559. connect(clearStackButton, SIGNAL(clicked()), this, SLOT(clearStack()));
  560. connect(stackButton, SIGNAL(toggled(bool)), this, SLOT(toggleStack(bool)));
  561. connect(historyButton, SIGNAL(toggled(bool)), this, SLOT(toggleHistory(bool)));
  562. connect(keypadButton, SIGNAL(toggled(bool)), this, SLOT(toggleKeypad(bool)));
  563. connect(kp0, SIGNAL(clicked()), this, SLOT(insertKP0()));
  564. connect(kp1, SIGNAL(clicked()), this, SLOT(insertKP1()));
  565. connect(kp2, SIGNAL(clicked()), this, SLOT(insertKP2()));
  566. connect(kp3, SIGNAL(clicked()), this, SLOT(insertKP3()));
  567. connect(kp4, SIGNAL(clicked()), this, SLOT(insertKP4()));
  568. connect(kp5, SIGNAL(clicked()), this, SLOT(insertKP5()));
  569. connect(kp6, SIGNAL(clicked()), this, SLOT(insertKP6()));
  570. connect(kp7, SIGNAL(clicked()), this, SLOT(insertKP7()));
  571. connect(kp8, SIGNAL(clicked()), this, SLOT(insertKP8()));
  572. connect(kp9, SIGNAL(clicked()), this, SLOT(insertKP9()));
  573. connect(kpDot, SIGNAL(clicked()), this, SLOT(insertDot()));
  574. connect(kpExp, SIGNAL(clicked()), this, SLOT(insertExp()));
  575. connect(kpAns, SIGNAL(clicked()), this, SLOT(insertAns()));
  576. connect(kpEquals, SIGNAL(clicked()), this, SLOT(execute()));
  577. connect(kpPlus, SIGNAL(clicked()), this, SLOT(insertPlus()));
  578. connect(kpMinus, SIGNAL(clicked()), this, SLOT(insertMinus()));
  579. connect(kpTimes, SIGNAL(clicked()), this, SLOT(insertTimes()));
  580. connect(kpDivision, SIGNAL(clicked()), this, SLOT(insertDivision()));
  581. connect(kpDel, SIGNAL(clicked()), this, SLOT(expressionDel()));
  582. connect(kpClear, SIGNAL(clicked()), this, SLOT(clearExpression()));
  583. connect(kpSin, SIGNAL(clicked()), this, SLOT(insertSin()));
  584. connect(kpCos, SIGNAL(clicked()), this, SLOT(insertCos()));
  585. connect(kpTan, SIGNAL(clicked()), this, SLOT(insertTan()));
  586. connect(kpSqrt, SIGNAL(clicked()), this, SLOT(insertSqrt()));
  587. connect(kpLog, SIGNAL(clicked()), this, SLOT(insertLog()));
  588. connect(kpLn, SIGNAL(clicked()), this, SLOT(insertLn()));
  589. connect(kpRaise, SIGNAL(clicked()), this, SLOT(insertRaise()));
  590. connect(kpSquare, SIGNAL(clicked()), this, SLOT(insertSquare()));
  591. connect(kpFraction, SIGNAL(toggled(bool)), this, SLOT(setFractionMode(bool)));
  592. connect(kpExact, SIGNAL(toggled(bool)), this, SLOT(setExactMode(bool)));
  593. connect(kpAngleGroup, SIGNAL(clicked(int)), this, SLOT(kpSetAngleUnit(int)));
  594. connect(kpBaseCombo->listBox(), SIGNAL(selected(int)), this, SLOT(kpSetBaseSelected(int)));
  595. connect(kpBaseCombo, SIGNAL(activated(int)), this, SLOT(kpSetBase(int)));
  596. connect(kpNumericCombo, SIGNAL(activated(int)), this, SLOT(kpSetNumericalMode(int)));
  597. //connect(kpMod, SIGNAL(clicked()), this, SLOT(insertMod()));
  598. connect(kpFactorial, SIGNAL(clicked()), this, SLOT(insertFactorial()));
  599. //connect(expressionEdit, SIGNAL(returnPressed()), this, SLOT(execute()));
  600. connect(expressionEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onExpressionChanged()));
  601. connect(storeButton, SIGNAL(clicked()), this, SLOT(storeResult()));
  602. connect(executeButton, SIGNAL(clicked()), this, SLOT(execute()));
  603. connect(convertButton, SIGNAL(clicked()), this, SLOT(convertToUnitExpression()));
  604. connect(functionsButton, SIGNAL(clicked()), this, SLOT(manageFunctions()));
  605. connect(expressionEdit, SIGNAL(cursorMoved()), this, SLOT(displayParseStatus()));
  606. connect(expressionEdit->qalculateCompletionBox, SIGNAL(hidden()), statusLabel_l, SLOT(update()));
  607. //tab order
  608. setTabOrder(expressionEdit, resultLabel);
  609. setTabOrder(resultLabel, historyBrowser);
  610. setTabOrder(historyBrowser, keypadButton);
  611. setTabOrder(keypadButton, historyButton);
  612. setTabOrder(historyButton, stackButton);
  613. if(show_stack && rpn_mode) {
  614. bottomLine->hide();
  615. stackButton->setOn(true);
  616. mainStack->raiseWidget(2);
  617. mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
  618. resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
  619. } else if(show_keypad) {
  620. bottomLine->hide();
  621. keypadButton->setOn(true);
  622. mainStack->raiseWidget(0);
  623. mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
  624. resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
  625. } else if(show_history) {
  626. bottomLine->hide();
  627. historyButton->setOn(true);
  628. mainStack->raiseWidget(1);
  629. mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
  630. resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
  631. } else {
  632. mainStack->hide();
  633. mainStack->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum, false);
  634. resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
  635. }
  636. initial_history = "";
  637. for(QValueVector<QString>::size_type i = 0; i < inhistory.size(); i++) {
  638. switch(inhistory_type[i]) {
  639. case QALCULATE_HISTORY_EXPRESSION: {
  640. if(i != 0) {
  641. initial_history += "<br><hr>";
  642. }
  643. initial_history += "<a name=\"";
  644. initial_history += QString::number(inhistory_id[i]);
  645. initial_history += "\">";
  646. initial_history += inhistory[i];
  647. initial_history += "</a>";
  648. initial_history += " ";
  649. break;
  650. }
  651. case QALCULATE_HISTORY_REGISTER_MOVED: {
  652. if(i != 0) {
  653. initial_history += "<br><hr>";
  654. }
  655. initial_history += i18n("RPN Register Moved");
  656. initial_history += "<br>";
  657. break;
  658. }
  659. case QALCULATE_HISTORY_TRANSFORMATION: {
  660. initial_history += "<i>";
  661. initial_history += "<b>";
  662. initial_history += inhistory[i];
  663. initial_history += "</i>";
  664. initial_history += ": ";
  665. break;
  666. }
  667. case QALCULATE_HISTORY_RESULT: {
  668. initial_history += "<a name=\"";
  669. initial_history += QString::number(inhistory_id[i]);
  670. initial_history += "\">";
  671. initial_history += "= ";
  672. initial_history += "</a>";
  673. initial_history += "<b>";
  674. initial_history += "<a name=\"";
  675. initial_history += QString::number(inhistory_id[i]);
  676. initial_history += "\">";
  677. initial_history += inhistory[i];
  678. initial_history += "</a>";
  679. initial_history += "</b>";
  680. initial_history += "<br>";
  681. break;
  682. }
  683. case QALCULATE_HISTORY_RESULT_APPROXIMATE: {
  684. initial_history += "<a name=\"";
  685. initial_history += QString::number(inhistory_id[i]);
  686. initial_history += "\">";
  687. if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) historyBrowser)) {
  688. initial_history += SIGN_ALMOST_EQUAL " ";
  689. } else {
  690. initial_history += "= ";
  691. initial_history += i18n("approx.");
  692. initial_history += " ";
  693. }
  694. initial_history += "</a>";
  695. initial_history += "<b>";
  696. initial_history += "<a name=\"";
  697. initial_history += QString::number(inhistory_id[i]);
  698. initial_history += "\">";
  699. initial_history += inhistory[i];
  700. initial_history += "</a>";
  701. initial_history += "</b>";
  702. initial_history += "<br>";
  703. break;
  704. }
  705. case QALCULATE_HISTORY_PARSE: {
  706. initial_history += "&nbsp;&nbsp;= ";
  707. initial_history += "<font color=\"gray40\"><i>";
  708. initial_history += "<a name=\"";
  709. initial_history += QString::number(inhistory_id[i]);
  710. initial_history += "\">";
  711. initial_history += inhistory[i];
  712. initial_history += "</a>";
  713. initial_history += "</i></font>";
  714. initial_history += "<br>";
  715. break;
  716. }
  717. case QALCULATE_HISTORY_PARSE_APPROXIMATE: {
  718. initial_history += "&nbsp;&nbsp;";
  719. if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) historyBrowser)) {
  720. initial_history += SIGN_ALMOST_EQUAL " ";
  721. } else {
  722. initial_history += "= ";
  723. initial_history += i18n("approx.");
  724. initial_history += " ";
  725. }
  726. initial_history += "<font color=\"gray40\"><i>";
  727. initial_history += "<a name=\"";
  728. initial_history += QString::number(inhistory_id[i]);
  729. initial_history += "\">";
  730. initial_history += inhistory[i];
  731. initial_history += "</a>";
  732. initial_history += "</i></font>";
  733. initial_history += "<br>";
  734. break;
  735. }
  736. case QALCULATE_HISTORY_WARNING: {
  737. initial_history += "<font color=\"blue\">";
  738. initial_history += "- ";
  739. initial_history += inhistory[i];
  740. initial_history += "</font>";
  741. initial_history += "<br>";
  742. break;
  743. }
  744. case QALCULATE_HISTORY_ERROR: {
  745. initial_history += "<font color=\"red\">";
  746. initial_history += "- ";
  747. initial_history += inhistory[i];
  748. initial_history += "</font>";
  749. initial_history += "<br>";
  750. break;
  751. }
  752. case QALCULATE_HISTORY_OLD: {
  753. initial_history += inhistory[i];
  754. initial_history += "<br>";
  755. break;
  756. }
  757. }
  758. }
  759. historyBrowser->setText(initial_history);
  760. initial_history = "";
  761. if(use_custom_result_font) {
  762. QFont new_font(resultLabel->font());
  763. new_font.fromString(custom_result_font);
  764. resultLabel->setFont(new_font);
  765. } else {
  766. resultLabel->unsetFont();
  767. }
  768. if(use_custom_expression_font) {
  769. QFont new_font(expressionEdit->font());
  770. new_font.fromString(custom_expression_font);
  771. expressionEdit->setFont(new_font);
  772. } else {
  773. expressionEdit->unsetFont();
  774. }
  775. updateStatusLabelFonts();
  776. set_unicode_buttons();
  777. setupActions();
  778. stackMenu = new QPopupMenu(this);
  779. ActionEditRegister->plug(stackMenu);
  780. ActionDeleteRegister->plug(stackMenu);
  781. stackMenu->insertSeparator();
  782. ActionClearStack->plug(stackMenu);
  783. update_status_text();
  784. bottomLine->setMinimumWidth(1000);
  785. createGUI("qalculate_kdeui.rc");
  786. menuBar()->sizeHint();
  787. int h = menuBar()->height();
  788. int w = 300;
  789. while(menuBar()->heightForWidth(w) > h && w < 1000) {
  790. w += 10;
  791. }
  792. if(w >= 1000) {
  793. bottomLine->setMinimumWidth(0);
  794. w = 0;
  795. } else {
  796. bottomLine->setMinimumWidth(w - 22);
  797. }
  798. if(!isShown()) adjustSize();
  799. setAutoSaveSettings();
  800. if(show_history || (rpn_mode && show_stack)) {
  801. resize(QSize(10, height()).expandedTo(minimumSizeHint()));
  802. } else if(show_keypad) {
  803. resize(minimumSizeHint());
  804. } else {
  805. resize(QSize(width(), 10).expandedTo(minimumSizeHint()));
  806. }
  807. menu_functions = (QPopupMenu*) factory()->container("functions", this);
  808. menu_variables = (QPopupMenu*) factory()->container("variables", this);
  809. menu_units = (QPopupMenu*) factory()->container("units", this);
  810. menu_to_unit = (QPopupMenu*) factory()->container("convert_to_unit", this);
  811. menu_set_prefix = (QPopupMenu*) factory()->container("set_prefix", this);
  812. menu_modes = (QPopupMenu*) factory()->container("modes", this);
  813. QObject::connect(menu_modes, SIGNAL(activated(int)), this, SLOT(onModesMenuItemActivated(int)));
  814. for(size_t i = 0; i < modes.size(); i++) {
  815. menu_modes->insertItem(modes[i].name, -1, i);
  816. if(i > 1) {
  817. ModeObject *mo = new ModeObject(i);
  818. mo->i_mode = i;
  819. mode_objects.push_back(mo);
  820. accel()->insert(QString("Load mode: ") + modes[i].name, i18n("Load meta mode: %1").arg(modes[i].name), QString::null, modes[i].shortcut, mo, SLOT(loadMode()));
  821. }
  822. }
  823. QObject::connect(menu_functions, SIGNAL(activated(int)), this, SLOT(onFunctionMenuItemActivated(int)));
  824. QObject::connect(menu_variables, SIGNAL(activated(int)), this, SLOT(onVariableMenuItemActivated(int)));
  825. QObject::connect(menu_units, SIGNAL(activated(int)), this, SLOT(onUnitMenuItemActivated(int)));
  826. QObject::connect(menu_to_unit, SIGNAL(activated(int)), this, SLOT(onConvertToUnitMenuItemActivated(int)));
  827. QObject::connect(menu_set_prefix, SIGNAL(activated(int)), this, SLOT(onSetPrefixMenuItemActivated(int)));
  828. }
  829. KQalculate::~KQalculate() {}
  830. void KQalculate::updateStatusLabelFonts() {
  831. if(use_custom_status_font) {
  832. QFont new_font(statusLabel_l->font());
  833. new_font.fromString(custom_status_font);
  834. statusLabel_l->setFont(new_font);
  835. new_font.setPointSizeFloat(new_font.pointSizeFloat() / 1.2);
  836. statusLabel_r->setFont(new_font);
  837. } else {
  838. statusLabel_l->unsetFont();
  839. statusLabel_r->unsetFont();
  840. QFont new_font = statusLabel_l->font();
  841. new_font.setPointSizeFloat(new_font.pointSizeFloat() / 1.2);
  842. statusLabel_l->setFont(new_font);
  843. new_font = statusLabel_r->font();
  844. new_font.setPointSizeFloat(new_font.pointSizeFloat() / 1.44);
  845. statusLabel_r->setFont(new_font);
  846. }
  847. }
  848. void KQalculate::updateButtonWidths() {
  849. int button_width = executeButton->sizeHint().width();
  850. if(storeButton->sizeHint().width() > button_width) button_width = storeButton->sizeHint().width();
  851. if(convertButton->sizeHint().width() > button_width) button_width = convertButton->sizeHint().width();
  852. if(registerUpButton->sizeHint().width() > button_width) button_width = registerUpButton->sizeHint().width();
  853. if(registerDownButton->sizeHint().width() > button_width) button_width = registerDownButton->sizeHint().width();
  854. if(editRegisterButton->sizeHint().width() > button_width) button_width = editRegisterButton->sizeHint().width();
  855. if(deleteRegisterButton->sizeHint().width() > button_width) button_width = deleteRegisterButton->sizeHint().width();
  856. if(clearStackButton->sizeHint().width() > button_width) button_width = clearStackButton->sizeHint().width();
  857. clearStackButton->setMinimumWidth(button_width);
  858. executeButton->setMinimumWidth(button_width);
  859. }
  860. void KQalculate::fontChange(const QFont &old_font) {
  861. updateStatusLabelFonts();
  862. functionsButton->unsetFont();
  863. QFont fb_font(functionsButton->font());
  864. fb_font.setItalic(true);
  865. functionsButton->setFont(fb_font);
  866. kpSquare->setMarkup(i18n("x<sup>2</sup>"));
  867. kpRaise->setMarkup(i18n("x<sup>y</sup>"));
  868. result_display_updated();
  869. KMainWindow::fontChange(old_font);
  870. updateButtonWidths();
  871. }
  872. void KQalculate::showSystemTrayIcon(bool do_show) {
  873. if(do_show && !trayicon) {
  874. trayicon = new KSystemTray(this);
  875. QObject::connect(trayicon, SIGNAL(quitSelected()), qApp, SLOT(quit()));
  876. #if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
  877. trayicon->setPixmap(loadSystrayIcon(PACKAGE));
  878. #else
  879. trayicon->setPixmap(trayicon->loadIcon(PACKAGE));
  880. #endif
  881. #if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 2
  882. KPopupMenu* traypop = trayicon->contextMenu();
  883. ActionHideSystemTrayIcon->plug(traypop, 1);
  884. #endif
  885. QToolTip::add(trayicon, i18n("Qalculate! - Scientific Calculator"));
  886. }
  887. if(do_show) {
  888. trayicon->show();
  889. } else if(trayicon) {
  890. trayicon->hide();
  891. }
  892. }
  893. void KQalculate::hideSystemTrayIcon() {
  894. showSystemTrayIcon(false);
  895. close_to_systray = false;
  896. show();
  897. }
  898. #define SET_TOGGLE_ACTION(action, value) action->blockSignals(true); action->setChecked(value); action->blockSignals(false);
  899. #define SET_TOGGLE_ACTION_ON(action) action->blockSignals(true); action->setChecked(true); action->blockSignals(false);
  900. void KQalculate::setupActions() {
  901. ActionNewVariable = new KAction(i18n("Variable"), "filenew", 0, this, SLOT(newVariable()), actionCollection(), "new_variable");
  902. ActionNewMatrix = new KAction(i18n("Matrix"), "filenew", 0, this, SLOT(newMatrix()), actionCollection(), "new_matrix");
  903. ActionNewVector = new KAction(i18n("Vector"), "filenew", 0, this, SLOT(newVector()), actionCollection(), "new_vector");
  904. ActionNewUnknownVariable = new KAction(i18n("Unknown Variable"), "filenew", 0, this, SLOT(newUnknownVariable()), actionCollection(), "new_unknown_variable");
  905. ActionNewFunction = new KAction(i18n("Function"), "filenew", 0, this, SLOT(newFunction()), actionCollection(), "new_function");
  906. ActionNewDataSet = new KAction(i18n("Data Set"), "filenew", 0, this, SLOT(newDataSet()), actionCollection(), "new_data_set");
  907. ActionNewUnit = new KAction(i18n("Unit"), "filenew", 0, this, SLOT(newUnit()), actionCollection(), "new_unit");
  908. ActionImportCSVFile = new KAction(i18n("Import CSV File..."), "fileimport", 0, this, SLOT(importCSVFile()), actionCollection(), "import_csv_file");
  909. ActionExportCSVFile = new KAction(i18n("Export CSV File..."), "filexport", 0, this, SLOT(exportCSVFile()), actionCollection(), "export_csv_file");
  910. ActionStoreResult = new KAction(i18n("Store Result..."), "filesave", CTRL+Key_S, this, SLOT(storeResult()), actionCollection(), "store_result");
  911. ActionSaveAsImage = new KAction(i18n("Save Result Image..."), "filesave", 0, this, SLOT(saveAsImage()), actionCollection(), "save_as_image");
  912. ActionSaveDefinitions = new KAction(i18n("Save Definitions"), "filesave", 0, this, SLOT(saveDefinitions()), actionCollection(), "save_definitions");
  913. ActionUpdateExchangeRates = new KAction(i18n("Update Exchange Rates"), "reload", 0, this, SLOT(updateExchangeRates()), actionCollection(), "update_exchange_rates");
  914. ActionPlotFunctionsData = new KAction(i18n("Plot Functions/Data"), 0, this, SLOT(plotFunctionsData()), actionCollection(), "plot_functions_data");
  915. ActionPlotFunctionsData->setEnabled(canplot);
  916. ActionConvertNumberBases = new KAction(i18n("Convert Number Bases"), 0, this, SLOT(convertNumberBases()), actionCollection(), "convert_number_bases");
  917. ActionPeriodicTable = new KAction(i18n("Periodic Table"), 0, this, SLOT(periodicTable()), actionCollection(), "periodic_table");
  918. if(close_to_systray) {
  919. ActionClose = KStdAction::close(this, SLOT(close()), actionCollection());
  920. } else {
  921. ActionClose = NULL;
  922. }
  923. globalAccel = new KGlobalAccel(this);
  924. globalAccel->insert("Show/hide Qalculate!", i18n("Show/hide main Qalculate! window"), QString::null, KShortcut(), KShortcut(), this, SLOT(showHide()));
  925. globalAccel->readSettings();
  926. globalAccel->updateConnections();
  927. ActionConfigureGlobalShortcuts = new KAction(i18n("Configure &Global Shortcuts..."), "configure_shortcuts", 0, this, SLOT(configureGlobalShortcuts()), actionCollection(), "configure_global_shortcuts");
  928. ActionQuit = KStdAction::quit(qApp, SLOT(quit()), actionCollection());
  929. ActionManageVariables = new KAction(i18n("Manage Variables"), Key_F2, this, SLOT(manageVariables()), actionCollection(), "manage_variables");
  930. ActionManageFunctions = new KAction(i18n("Manage Functions"), Key_F3, this, SLOT(manageFunctions()), actionCollection(), "manage_functions");
  931. ActionManageUnits = new KAction(i18n("Manage Units"), Key_F4, this, SLOT(manageUnits()), actionCollection(), "manage_units");
  932. ActionManageDataSets = new KAction(i18n("Manage Data Sets"), 0, this, SLOT(manageDataSets()), actionCollection(), "manage_data_sets");
  933. ActionFactorize = new KAction(i18n("Factorize"), 0, this, SLOT(factorize()), actionCollection(), "factorize");
  934. ActionSimplify = new KAction(i18n("Simplify"), 0, this, SLOT(simplify()), actionCollection(), "simplify");
  935. ActionSetUnknowns = new KAction(i18n("Set Unknowns..."), 0, this, SLOT(setUnknowns()), actionCollection(), "set_unknowns");
  936. ActionConvertToUnitExpression = new KAction(i18n("Convert to Unit Expression..."), CTRL+Key_T, this, SLOT(convertToUnitExpression()), actionCollection(), "convert_to_unit_expression");
  937. ActionConvertToBaseUnits = new KAction(i18n("Convert to Base Units"), 0, this, SLOT(convertToBaseUnits()), actionCollection(), "convert_to_base_units");
  938. ActionConvertToBestUnit = new KAction(i18n("Convert to Best Unit"), 0, this, SLOT(convertToBestUnit()), actionCollection(), "convert_to_best_unit");
  939. ActionInsertMatrix = new KAction(i18n("Insert Matrix..."), 0, this, SLOT(insertMatrix()), actionCollection(), "insert_matrix");
  940. ActionInsertVector = new KAction(i18n("Insert Vector..."), 0, this, SLOT(insertVector()), actionCollection(), "insert_vector");
  941. ActionCopyResult = new KAction(i18n("Copy Result"), "editcopy", Key_F5, this, SLOT(copyResult()), actionCollection(), "copy_result");
  942. ActionClearHistory = new KAction(i18n("Clear History"), "editclear", 0, this, SLOT(clearHistory()), actionCollection(), "clear_history");
  943. ActionPreferences = new KAction(i18n("Configure Qalculate!"), "configure", 0, this, SLOT(preferences()), actionCollection(), "preferences");
  944. KStdAction::keyBindings(guiFactory(), SLOT(configureShortcuts()), actionCollection(), "keybindings");
  945. ActionNumberBaseBinary = new KRadioAction(i18n("Binary"), 0, this, SLOT(numberBaseBinary()), actionCollection(), "number_base_binary");
  946. ActionNumberBaseBinary->setExclusiveGroup("group_number_base");
  947. ActionNumberBaseOctal = new KRadioAction(i18n("Octal"), 0, this, SLOT(numberBaseOctal()), actionCollection(), "number_base_octal");
  948. ActionNumberBaseOctal->setExclusiveGroup("group_number_base");
  949. ActionNumberBaseDecimal = new KRadioAction(i18n("Decimal"), 0, this, SLOT(numberBaseDecimal()), actionCollection(), "number_base_decimal");
  950. ActionNumberBaseDecimal->setExclusiveGroup("group_number_base");
  951. ActionNumberBaseHexadecimal = new KRadioAction(i18n("Hexadecimal"), 0, this, SLOT(numberBaseHexadecimal()), actionCollection(), "number_base_hexadecimal");
  952. ActionNumberBaseHexadecimal->setExclusiveGroup("group_number_base");
  953. ActionNumberBaseOther = new KRadioAction(i18n("Other..."), 0, this, SLOT(numberBaseOther()), actionCollection(), "number_base_other");
  954. ActionNumberBaseOther->setExclusiveGroup("group_number_base");
  955. ActionNumberBaseSexagesimal = new KRadioAction(i18n("Sexagesimal"), 0, this, SLOT(numberBaseSexagesimal()), actionCollection(), "number_base_sexagesimal");
  956. ActionNumberBaseSexagesimal->setExclusiveGroup("group_number_base");
  957. ActionNumberBaseTimeFormat = new KRadioAction(i18n("Time Format"), 0, this, SLOT(numberBaseTimeFormat()), actionCollection(), "number_base_time_format");
  958. ActionNumberBaseTimeFormat->setExclusiveGroup("group_number_base");
  959. ActionNumberBaseRomanNumerals = new KRadioAction(i18n("Roman Numerals"), 0, this, SLOT(numberBaseRomanNumerals()), actionCollection(), "number_base_roman_numerals");
  960. ActionNumberBaseRomanNumerals->setExclusiveGroup("group_number_base");
  961. ActionSetBase = new KAction(i18n("Select Result and Expression Base..."), CTRL+Key_B, this, SLOT(setBase()), actionCollection(), "set_base");
  962. ActionNumericalDisplayNormal = new KRadioAction(i18n("Normal"), 0, this, SLOT(numericalDisplayNormal()), actionCollection(), "numerical_display_normal");
  963. ActionNumericalDisplayNormal->setExclusiveGroup("group_numberical_display");
  964. ActionNumericalDisplayEngineering = new KRadioAction(i18n("Engineering"), 0, this, SLOT(numericalDisplayEngineering()), actionCollection(), "numerical_display_engineering");
  965. ActionNumericalDisplayEngineering->setExclusiveGroup("group_numberical_display");
  966. ActionNumericalDisplayScientific = new KRadioAction(i18n("Scientific"), 0, this, SLOT(numericalDisplayScientific()), actionCollection(), "numerical_display_scientific");
  967. ActionNumericalDisplayScientific->setExclusiveGroup("group_numberical_display");
  968. ActionNumericalDisplayPurelyScientific = new KRadioAction(i18n("Purely Scientific"), 0, this, SLOT(numericalDisplayPurelyScientific()), actionCollection(), "numerical_display_purely_scientific");
  969. ActionNumericalDisplayPurelyScientific->setExclusiveGroup("group_numberical_display");
  970. ActionNumericalDisplaySimple = new KRadioAction(i18n("Simple"), 0, this, SLOT(numericalDisplaySimple()), actionCollection(), "numerical_display_simple");
  971. ActionNumericalDisplaySimple->setExclusiveGroup("group_numberical_display");
  972. ActionIndicateInfiniteSeries = new KToggleAction(i18n("Indicate Infinite Series"), 0, actionCollection(), "indicate_infinite_series");
  973. QObject::connect(ActionIndicateInfiniteSeries, SIGNAL(toggled(bool)), this, SLOT(indicateInfiniteSeries(bool)));
  974. ActionSortMinusLast = new KToggleAction(i18n("Sort Minus Last"), 0, actionCollection(), "sort_minus_last");
  975. QObject::connect(ActionSortMinusLast, SIGNAL(toggled(bool)), this, SLOT(sortMinusLast(bool)));
  976. ActionNegativeExponents = new KToggleAction(i18n("Negative Exponents"), 0, actionCollection(), "negative_exponents");
  977. QObject::connect(ActionNegativeExponents, SIGNAL(toggled(bool)), this, SLOT(negativeExponents(bool)));
  978. ActionShowEndingZeroes = new KToggleAction(i18n("Show Ending Zeroes"), 0, actionCollection(), "show_ending_zeroes");
  979. QObject::connect(ActionShowEndingZeroes, SIGNAL(toggled(bool)), this, SLOT(showEndingZeroes(bool)));
  980. ActionRoundHalfwayNumbersToEven = new KToggleAction(i18n("Round Halfway Numbers to Even"), 0, actionCollection(), "round_halfway_numbers_to_even");
  981. QObject::connect(ActionRoundHalfwayNumbersToEven, SIGNAL(toggled(bool)), this, SLOT(roundHalfwayNumbersToEven(bool)));
  982. ActionFractionalDisplayDecimal = new KRadioAction(i18n("Decimal"), 0, this, SLOT(fractionalDisplayDecimal()), actionCollection(), "fractional_display_decimal");
  983. ActionFractionalDisplayDecimal->setExclusiveGroup("group_fractional_display");
  984. ActionFractionalDisplayDecimalTryExact = new KRadioAction(i18n("Decimal (Try Exact)"), 0, this, SLOT(fractionalDisplayDecimalTryExact()), actionCollection(), "fractional_display_decimal_try_exact");
  985. ActionFractionalDisplayDecimalTryExact->setExclusiveGroup("group_fractional_display");
  986. ActionFractionalDisplayFraction = new KRadioAction(i18n("Fraction"), 0, this, SLOT(fractionalDisplayFraction()), actionCollection(), "fractional_display_fraction");
  987. ActionFractionalDisplayFraction->setExclusiveGroup("group_fractional_display");
  988. ActionFractionalDisplayCombined = new KRadioAction(i18n("Combined"), 0, this, SLOT(fractionalDisplayCombined()), actionCollection(), "fractional_display_combined");
  989. ActionFractionalDisplayCombined->setExclusiveGroup("group_fractional_display");
  990. ActionEnablePrefixes = new KToggleAction(i18n("Enable Prefixes"), 0, actionCollection(), "enable_prefixes");
  991. QObject::connect(ActionEnablePrefixes, SIGNAL(toggled(bool)), this, SLOT(enablePrefixes(bool)));
  992. ActionEnableUseOfAllPrefixes = new KToggleAction(i18n("Enable Use of All SI Prefixes"), 0, actionCollection(), "enable_use_of_all_prefixes");
  993. QObject::connect(ActionEnableUseOfAllPrefixes, SIGNAL(toggled(bool)), this, SLOT(enableUseOfAllPrefixes(bool)));
  994. ActionEnableDenominatorPrefixes = new KToggleAction(i18n("Enable Denominator Prefixes"), 0, actionCollection(), "enable_denominator_prefixes");
  995. QObject::connect(ActionEnableDenominatorPrefixes, SIGNAL(toggled(bool)), this, SLOT(enableDenominatorPrefixes(bool)));
  996. ActionPlaceUnitsSeparately = new KToggleAction(i18n("Place Units Separately"), 0, actionCollection(), "place_units_separately");
  997. QObject::connect(ActionPlaceUnitsSeparately, SIGNAL(toggled(bool)), this, SLOT(placeUnitsSeparately(bool)));
  998. ActionAutoNoConversion = new KRadioAction(i18n("No Automatic Conversion"), 0, this, SLOT(autoNoConversion()), actionCollection(), "auto_no_conversion");
  999. ActionAutoNoConversion->setExclusiveGroup("group_auto_conversion");
  1000. ActionAutoConvertToBaseUnits = new KRadioAction(i18n("Convert to Base Units"), 0, this, SLOT(autoConvertToBaseUnits()), actionCollection(), "auto_convert_to_base_units");
  1001. ActionAutoConvertToBaseUnits->setExclusiveGroup("group_auto_conversion");
  1002. ActionAutoConvertToBestUnit = new KRadioAction(i18n("Convert to Best Unit"), 0, this, SLOT(autoConvertToBestUnit()), actionCollection(), "auto_convert_to_best_unit");
  1003. ActionAutoConvertToBestUnit->setExclusiveGroup("group_auto_conversion");
  1004. ActionAngleUnitDegrees = new KRadioAction(i18n("Degrees"), 0, this, SLOT(angleUnitDegrees()), actionCollection(), "angle_unit_degrees");
  1005. ActionAngleUnitDegrees->setExclusiveGroup("group_angle_unit");
  1006. ActionAngleUnitRadians = new KRadioAction(i18n("Radians"), 0, this, SLOT(angleUnitRadians()), actionCollection(), "angle_unit_radians");
  1007. ActionAngleUnitRadians->setExclusiveGroup("group_angle_unit");
  1008. ActionAngleUnitGradians = new KRadioAction(i18n("Gradians"), 0, this, SLOT(angleUnitGradians()), actionCollection(), "angle_unit_gradians");
  1009. ActionAngleUnitGradians->setExclusiveGroup("group_angle_unit");
  1010. ActionAngleUnitNone = new KRadioAction(i18n("None"), 0, this, SLOT(angleUnitNone()), actionCollection(), "angle_unit_none");
  1011. ActionAngleUnitNone->setExclusiveGroup("group_angle_unit");
  1012. ActionAbbreviateNames = new KToggleAction(i18n("Abbreviate Names"), 0, actionCollection(), "abbreviate_names");
  1013. QObject::connect(ActionAbbreviateNames, SIGNAL(toggled(bool)), this, SLOT(abbreviateNames(bool)));
  1014. ActionEnableVariables = new KToggleAction(i18n("Enable Variables"), 0, actionCollection(), "enable_variables");
  1015. QObject::connect(ActionEnableVariables, SIGNAL(toggled(bool)), this, SLOT(enableVariables(bool)));
  1016. ActionEnableFunctions = new KToggleAction(i18n("Enable Functions"), 0, actionCollection(), "enable_functions");
  1017. QObject::connect(ActionEnableFunctions, SIGNAL(toggled(bool)), this, SLOT(enableFunctions(bool)));
  1018. ActionEnableUnits = new KToggleAction(i18n("Enable Units"), 0, actionCollection(), "enable_units");
  1019. QObject::connect(ActionEnableUnits, SIGNAL(toggled(bool)), this, SLOT(enableUnits(bool)));
  1020. ActionEnableUnknowns = new KToggleAction(i18n("Enable Unknowns"), 0, actionCollection(), "enable_unknowns");
  1021. QObject::connect(ActionEnableUnknowns, SIGNAL(toggled(bool)), this, SLOT(enableUnknowns(bool)));
  1022. ActionCalculateVariables = new KToggleAction(i18n("Calculate Variables"), 0, actionCollection(), "calculate_variables");
  1023. QObject::connect(ActionCalculateVariables, SIGNAL(toggled(bool)), this, SLOT(calculateVariables(bool)));
  1024. ActionAllowComplexResult = new KToggleAction(i18n("Allow Complex Result"), 0, actionCollection(), "allow_complex_result");
  1025. QObject::connect(ActionAllowComplexResult, SIGNAL(toggled(bool)), this, SLOT(allowComplexResult(bool)));
  1026. ActionAllowInfiniteResult = new KToggleAction(i18n("Allow Infinite Result"), 0, actionCollection(), "allow_infinite_result");
  1027. QObject::connect(ActionAllowInfiniteResult, SIGNAL(toggled(bool)), this, SLOT(allowInfiniteResult(bool)));
  1028. ActionApproximationTryExact = new KRadioAction(i18n("Try Exact"), 0, this, SLOT(approximationTryExact()), actionCollection(), "approximation_try_exact");
  1029. ActionApproximationTryExact->setExclusiveGroup("group_approximation");
  1030. ActionApproximationAlwaysExact = new KRadioAction(i18n("Always Exact"), 0, this, SLOT(approximationAlwaysExact()), actionCollection(), "approximation_always_exact");
  1031. ActionApproximationAlwaysExact->setExclusiveGroup("group_approximation");
  1032. ActionApproximationApproximate = new KRadioAction(i18n("Approximate"), 0, this, SLOT(approximationApproximate()), actionCollection(), "approximation_approximate");
  1033. ActionApproximationApproximate->setExclusiveGroup("group_approximation");
  1034. ActionAssumptionTypeUnknown = new KRadioAction(i18n("Unknown"), 0, this, SLOT(assumptionTypeUnknown()), actionCollection(), "assumption_type_unknown");
  1035. ActionAssumptionTypeUnknown->setExclusiveGroup("group_assumption_type");
  1036. ActionAssumptionTypeNonMatrix = new KRadioAction(i18n("Not Matrix"), 0, this, SLOT(assumptionTypeNonMatrix()), actionCollection(), "assumption_type_nonmatrix");
  1037. ActionAssumptionTypeNonMatrix->setExclusiveGroup("group_assumption_type");
  1038. ActionAssumptionTypeNumber = new KRadioAction(i18n("Number"), 0, this, SLOT(assumptionTypeNumber()), actionCollection(), "assumption_type_number");
  1039. ActionAssumptionTypeNumber->setExclusiveGroup("group_assumption_type");
  1040. ActionAssumptionTypeComplex = new KRadioAction(i18n("Complex"), 0, this, SLOT(assumptionTypeComplex()), actionCollection(), "assumption_type_complex");
  1041. ActionAssumptionTypeComplex->setExclusiveGroup("group_assumption_type");
  1042. ActionAssumptionTypeReal = new KRadioAction(i18n("Real"), 0, this, SLOT(assumptionTypeReal()), actionCollection(), "assumption_type_real");
  1043. ActionAssumptionTypeReal->setExclusiveGroup("group_assumption_type");
  1044. ActionAssumptionTypeRational = new KRadioAction(i18n("Rational"), 0, this, SLOT(assumptionTypeRational()), actionCollection(), "assumption_type_rational");
  1045. ActionAssumptionTypeRational->setExclusiveGroup("group_assumption_type");
  1046. ActionAssumptionTypeInteger = new KRadioAction(i18n("Integer"), 0, this, SLOT(assumptionTypeInteger()), actionCollection(), "assumption_type_integer");
  1047. ActionAssumptionTypeInteger->setExclusiveGroup("group_assumption_type");
  1048. ActionAssumptionSignUnknown = new KRadioAction(i18n("Unknown"), 0, this, SLOT(assumptionSignUnknown()), actionCollection(), "assumption_sign_unknown");
  1049. ActionAssumptionSignUnknown->setExclusiveGroup("group_assumption_sign");
  1050. ActionAssumptionSignNonZero = new KRadioAction(i18n("Non-Zero"), 0, this, SLOT(assumptionSignNonZero()), actionCollection(), "assumption_sign_non_zero");
  1051. ActionAssumptionSignNonZero->setExclusiveGroup("group_assumption_sign");
  1052. ActionAssumptionSignPositive = new KRadioAction(i18n("Positive"), 0, this, SLOT(assumptionSignPositive()), actionCollection(), "assumption_sign_positive");
  1053. ActionAssumptionSignPositive->setExclusiveGroup("group_assumption_sign");
  1054. ActionAssumptionSignNonNegative = new KRadioAction(i18n("Non-Negative"), 0, this, SLOT(assumptionSignNonNegative()), actionCollection(), "assumption_sign_non_negative");
  1055. ActionAssumptionSignNonNegative->setExclusiveGroup("group_assumption_sign");
  1056. ActionAssumptionSignNegative = new KRadioAction(i18n("Negative"), 0, this, SLOT(assumptionSignNegative()), actionCollection(), "assumption_sign_negative");
  1057. ActionAssumptionSignNegative->setExclusiveGroup("group_assumption_sign");
  1058. ActionAssumptionSignNonPositive = new KRadioAction(i18n("Non-Positive"), 0, this, SLOT(assumptionSignNonPositive()), actionCollection(), "assumption_sign_non_positive");
  1059. ActionAssumptionSignNonPositive->setExclusiveGroup("group_assumption_sign");
  1060. ActionNonZeroDenominators = new KToggleAction(i18n("Non-Zero Denominators"), 0, actionCollection(), "non_zero_denominators");
  1061. QObject::connect(ActionNonZeroDenominators, SIGNAL(toggled(bool)), this, SLOT(nonZeroDenominators(bool)));
  1062. ActionWarnAboutDenominatorsAssumedNonZero = new KToggleAction(i18n("Warn About Denominators Assumed Non-Zero"), 0, actionCollection(), "warn_about_denominators_assumed_nonzero");
  1063. QObject::connect(ActionWarnAboutDenominatorsAssumedNonZero, SIGNAL(toggled(bool)), this, SLOT(warnAboutDenominatorsAssumedNonZero(bool)));
  1064. ActionAlgebraicModeSimplify = new KRadioAction(i18n("Simplify"), 0, this, SLOT(algebraicModeSimplify()), actionCollection(), "algebraic_mode_simplify");
  1065. ActionAlgebraicModeSimplify->setExclusiveGroup("group_alebraic_mode");
  1066. ActionAlgebraicModeFactorize = new KRadioAction(i18n("Factorize"), 0, this, SLOT(algebraicModeFactorize()), actionCollection(), "algebraic_mode_factorize");
  1067. ActionAlgebraicModeFactorize->setExclusiveGroup("group_alebraic_mode");
  1068. ActionAlgebraicModeNone = new KRadioAction(i18n("None"), 0, this, SLOT(algebraicModeNone()), actionCollection(), "algebraic_mode_none");
  1069. ActionAlgebraicModeNone->setExclusiveGroup("group_alebraic_mode");
  1070. ActionReadPrecision = new KToggleAction(i18n("Read Precision"), 0, actionCollection(), "read_precision");
  1071. QObject::connect(ActionReadPrecision, SIGNAL(toggled(bool)), this, SLOT(readPrecision(bool)));
  1072. ActionLimitImplicitMultiplication = new KToggleAction(i18n("Limit Implicit Multiplication"), 0, actionCollection(), "limit_implicit_multiplication");
  1073. QObject::connect(ActionLimitImplicitMultiplication, SIGNAL(toggled(bool)), this, SLOT(limitImplicitMultiplication(bool)));
  1074. ActionRPNMode = new KToggleAction(i18n("RPN Mode"), CTRL+Key_R, actionCollection(), "rpn_mode");
  1075. QObject::connect(ActionRPNMode, SIGNAL(toggled(bool)), this, SLOT(rpnMode(bool)));
  1076. ActionRPNSyntax = new KToggleAction(i18n("RPN Syntax"), 0, actionCollection(), "rpn_syntax");
  1077. QObject::connect(ActionRPNSyntax, SIGNAL(toggled(bool)), this, SLOT(rpnSyntax(bool)));
  1078. ActionPrecision = new KAction(i18n("Precision"), 0, this, SLOT(precision()), actionCollection(), "precision");
  1079. ActionDecimals = new KAction(i18n("Decimals"), 0, this, SLOT(decimals()), actionCollection(), "decimals");
  1080. ActionSaveModeAs = new KAction(i18n("Save Mode..."), "filesave", 0, this, SLOT(saveModeAs()), actionCollection(), "save_mode_as");
  1081. ActionDeleteMode = new KAction(i18n("Delete Mode..."), "editdelete", 0, this, SLOT(deleteMode()), actionCollection(), "delete_mode");
  1082. ActionDeleteMode->setEnabled(modes.size() > 2);
  1083. ActionSaveMode = new KAction(i18n("Save Default Mode"), "filesave", 0, this, SLOT(saveMode()), actionCollection(), "save_mode");
  1084. ActionClearStack = new KAction(i18n("Clear Stack"), "view_remove", 0, this, SLOT(clearStack()), actionCollection(), "clear_stack");
  1085. ActionDeleteRegister = new KAction(i18n("Delete"), "editdelete", 0, this, SLOT(deleteRegister()), actionCollection(), "delete_register");
  1086. ActionEditRegister = new KAction(i18n("Edit"), "edit", 0, this, SLOT(editRegister()), actionCollection(), "edit_register");
  1087. new KAction(i18n("Exp RPN Operation"), CTRL+SHIFT+Key_E, this, SLOT(insertExp()), actionCollection(), "rpn_exp10");
  1088. setModeActions();
  1089. }
  1090. void KQalculate::setAssumptionsMenu() {
  1091. switch(CALCULATOR->defaultAssumptions()->sign()) {
  1092. case ASSUMPTION_SIGN_POSITIVE: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignPositive); break;}
  1093. case ASSUMPTION_SIGN_NONPOSITIVE: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignNonPositive); break;}
  1094. case ASSUMPTION_SIGN_NEGATIVE: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignNegative); break;}
  1095. case ASSUMPTION_SIGN_NONNEGATIVE: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignNonNegative); break;}
  1096. case ASSUMPTION_SIGN_NONZERO: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignNonZero); break;}
  1097. default: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignUnknown); }
  1098. }
  1099. switch(CALCULATOR->defaultAssumptions()->type()) {
  1100. case ASSUMPTION_TYPE_INTEGER: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeInteger); break;}
  1101. case ASSUMPTION_TYPE_RATIONAL: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeRational); break;}
  1102. case ASSUMPTION_TYPE_COMPLEX: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeComplex); break;}
  1103. case ASSUMPTION_TYPE_NUMBER: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeNumber); break;}
  1104. case ASSUMPTION_TYPE_REAL: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeReal); break;}
  1105. case ASSUMPTION_TYPE_NONMATRIX: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeNonMatrix); break;}
  1106. default: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeUnknown); }
  1107. }
  1108. }
  1109. void KQalculate::setModeActions() {
  1110. SET_TOGGLE_ACTION(ActionAllowComplexResult, evalops.allow_complex)
  1111. SET_TOGGLE_ACTION(ActionAllowInfiniteResult, evalops.allow_infinite)
  1112. SET_TOGGLE_ACTION(ActionEnableVariables, evalops.parse_options.variables_enabled)
  1113. SET_TOGGLE_ACTION(ActionEnableFunctions, evalops.parse_options.functions_enabled)
  1114. SET_TOGGLE_ACTION(ActionEnableUnits, evalops.parse_options.units_enabled)
  1115. SET_TOGGLE_ACTION(ActionEnableUnknowns, evalops.parse_options.unknowns_enabled)
  1116. SET_TOGGLE_ACTION(ActionCalculateVariables, evalops.calculate_variables)
  1117. SET_TOGGLE_ACTION(ActionReadPrecision, evalops.parse_options.read_precision != DONT_READ_PRECISION)
  1118. SET_TOGGLE_ACTION(ActionLimitImplicitMultiplication, evalops.parse_options.limit_implicit_multiplication)
  1119. SET_TOGGLE_ACTION(ActionRPNSyntax, evalops.parse_options.rpn)
  1120. SET_TOGGLE_ACTION(ActionRPNMode, rpn_mode)
  1121. SET_TOGGLE_ACTION(ActionNonZeroDenominators, evalops.assume_denominators_nonzero)
  1122. SET_TOGGLE_ACTION(ActionWarnAboutDenominatorsAssumedNonZero, evalops.warn_about_denominators_assumed_nonzero)
  1123. SET_TOGGLE_ACTION(ActionAbbreviateNames, printops.abbreviate_names)
  1124. SET_TOGGLE_ACTION(ActionIndicateInfiniteSeries, printops.indicate_infinite_series)
  1125. SET_TOGGLE_ACTION(ActionSortMinusLast, printops.sort_options.minus_last)
  1126. SET_TOGGLE_ACTION(ActionNegativeExponents, printops.negative_exponents)
  1127. SET_TOGGLE_ACTION(ActionShowEndingZeroes, printops.show_ending_zeroes)
  1128. SET_TOGGLE_ACTION(ActionRoundHalfwayNumbersToEven, printops.round_halfway_to_even)
  1129. SET_TOGGLE_ACTION(ActionEnablePrefixes, printops.use_unit_prefixes)
  1130. SET_TOGGLE_ACTION(ActionEnableUseOfAllPrefixes, printops.use_all_prefixes)
  1131. SET_TOGGLE_ACTION(ActionEnableDenominatorPrefixes, printops.use_denominator_prefix)
  1132. SET_TOGGLE_ACTION(ActionPlaceUnitsSeparately, printops.place_units_separately)
  1133. kpExact->blockSignals(true);
  1134. switch(evalops.approximation) {
  1135. case APPROXIMATION_EXACT: {
  1136. SET_TOGGLE_ACTION_ON(ActionApproximationAlwaysExact);
  1137. kpExact->setOn(true);
  1138. break;
  1139. }
  1140. case APPROXIMATION_TRY_EXACT: {
  1141. SET_TOGGLE_ACTION_ON(ActionApproximationTryExact);
  1142. kpExact->setOn(false);
  1143. break;
  1144. }
  1145. case APPROXIMATION_APPROXIMATE: {
  1146. SET_TOGGLE_ACTION_ON(ActionApproximationApproximate);
  1147. kpExact->setOn(false);
  1148. break;
  1149. }
  1150. }
  1151. kpExact->blockSignals(false);
  1152. switch(evalops.auto_post_conversion) {
  1153. case POST_CONVERSION_BEST: {
  1154. SET_TOGGLE_ACTION_ON(ActionAutoConvertToBestUnit);
  1155. break;
  1156. }
  1157. case POST_CONVERSION_BASE: {
  1158. SET_TOGGLE_ACTION_ON(ActionAutoConvertToBaseUnits);
  1159. break;
  1160. }
  1161. default: {
  1162. SET_TOGGLE_ACTION_ON(ActionAutoNoConversion);
  1163. }
  1164. }
  1165. kpAngleGroup->blockSignals(true);
  1166. switch(evalops.parse_options.angle_unit) {
  1167. case ANGLE_UNIT_DEGREES: {
  1168. SET_TOGGLE_ACTION_ON(ActionAngleUnitDegrees);
  1169. kpAngleGroup->setButton(0);
  1170. break;
  1171. }
  1172. case ANGLE_UNIT_RADIANS: {
  1173. SET_TOGGLE_ACTION_ON(ActionAngleUnitRadians);
  1174. kpAngleGroup->setButton(1);
  1175. break;
  1176. }
  1177. case ANGLE_UNIT_GRADIANS: {
  1178. SET_TOGGLE_ACTION_ON(ActionAngleUnitGradians);
  1179. kpAngleGroup->setButton(2);
  1180. break;
  1181. }
  1182. default: {
  1183. SET_TOGGLE_ACTION_ON(ActionAngleUnitNone);
  1184. kpAngleGroup->setButton(3);
  1185. }
  1186. }
  1187. kpAngleGroup->blockSignals(false);
  1188. kpBaseCombo->blockSignals(true);
  1189. switch(printops.base) {
  1190. case BASE_BINARY: {
  1191. SET_TOGGLE_ACTION_ON(ActionNumberBaseBinary);
  1192. kpBaseCombo->setCurrentItem(0);
  1193. break;
  1194. }
  1195. case BASE_OCTAL: {
  1196. SET_TOGGLE_ACTION_ON(ActionNumberBaseOctal);
  1197. kpBaseCombo->setCurrentItem(1);
  1198. break;
  1199. }
  1200. case BASE_DECIMAL: {
  1201. SET_TOGGLE_ACTION_ON(ActionNumberBaseDecimal);
  1202. kpBaseCombo->setCurrentItem(2);
  1203. break;
  1204. }
  1205. case BASE_HEXADECIMAL: {
  1206. SET_TOGGLE_ACTION_ON(ActionNumberBaseHexadecimal);
  1207. kpBaseCombo->setCurrentItem(3);
  1208. break;
  1209. }
  1210. case BASE_ROMAN_NUMERALS: {
  1211. SET_TOGGLE_ACTION_ON(ActionNumberBaseRomanNumerals);
  1212. kpBaseCombo->setCurrentItem(6);
  1213. break;
  1214. }
  1215. case BASE_SEXAGESIMAL: {
  1216. SET_TOGGLE_ACTION_ON(ActionNumberBaseSexagesimal);
  1217. kpBaseCombo->setCurrentItem(4);
  1218. break;
  1219. }
  1220. case BASE_TIME: {
  1221. SET_TOGGLE_ACTION_ON(ActionNumberBaseTimeFormat);
  1222. kpBaseCombo->setCurrentItem(5);
  1223. break;
  1224. }
  1225. default: {
  1226. SET_TOGGLE_ACTION_ON(ActionNumberBaseOther);
  1227. kpBaseCombo->setCurrentItem(7);
  1228. }
  1229. }
  1230. kpBaseCombo->blockSignals(false);
  1231. kpNumericCombo->blockSignals(true);
  1232. switch(printops.min_exp) {
  1233. case EXP_PRECISION: {
  1234. SET_TOGGLE_ACTION_ON(ActionNumericalDisplayNormal);
  1235. kpNumericCombo->setCurrentItem(0);
  1236. break;
  1237. }
  1238. case EXP_BASE_3: {
  1239. SET_TOGGLE_ACTION_ON(ActionNumericalDisplayEngineering);
  1240. kpNumericCombo->setCurrentItem(1);
  1241. break;
  1242. }
  1243. case EXP_SCIENTIFIC: {
  1244. SET_TOGGLE_ACTION_ON(ActionNumericalDisplayScientific);
  1245. kpNumericCombo->setCurrentItem(2);
  1246. break;
  1247. }
  1248. case EXP_PURE: {
  1249. SET_TOGGLE_ACTION_ON(ActionNumericalDisplayPurelyScientific);
  1250. kpNumericCombo->setCurrentItem(3);
  1251. break;
  1252. }
  1253. case EXP_NONE: {
  1254. SET_TOGGLE_ACTION_ON(ActionNumericalDisplaySimple);
  1255. kpNumericCombo->setCurrentItem(4);
  1256. break;
  1257. }
  1258. }
  1259. kpNumericCombo->blockSignals(false);
  1260. kpFraction->blockSignals(true);
  1261. switch (printops.number_fraction_format) {
  1262. case FRACTION_DECIMAL: {
  1263. SET_TOGGLE_ACTION_ON(ActionFractionalDisplayDecimal);
  1264. kpFraction->setOn(false);
  1265. break;
  1266. }
  1267. case FRACTION_DECIMAL_EXACT: {
  1268. SET_TOGGLE_ACTION_ON(ActionFractionalDisplayDecimalTryExact);
  1269. kpFraction->setOn(false);
  1270. break;
  1271. }
  1272. case FRACTION_COMBINED: {
  1273. SET_TOGGLE_ACTION_ON(ActionFractionalDisplayCombined);
  1274. kpFraction->setOn(true);
  1275. break;
  1276. }
  1277. case FRACTION_FRACTIONAL: {
  1278. SET_TOGGLE_ACTION_ON(ActionFractionalDisplayFraction);
  1279. kpFraction->setOn(true);
  1280. break;
  1281. }
  1282. }
  1283. kpFraction->blockSignals(false);
  1284. setAssumptionsMenu();
  1285. switch(evalops.structuring) {
  1286. case STRUCTURING_SIMPLIFY: {SET_TOGGLE_ACTION_ON(ActionAlgebraicModeSimplify); break;}
  1287. case STRUCTURING_FACTORIZE: {SET_TOGGLE_ACTION_ON(ActionAlgebraicModeFactorize); break;}
  1288. default: {SET_TOGGLE_ACTION_ON(ActionAlgebraicModeNone); }
  1289. }
  1290. }
  1291. #define TEXT_TAGS "<font size=6>"
  1292. #define TEXT_TAGS_END "</font>"
  1293. #define TEXT_TAGS_SMALL "<font size=5>"
  1294. #define TEXT_TAGS_SMALL_END "</font>"
  1295. #define TEXT_TAGS_XSMALL "<font size=4>"
  1296. #define TEXT_TAGS_XSMALL_END "</font>"
  1297. #define STR_MARKUP_ADD_SMALL(str, str_add) if(ips.power_depth > 0) {str += TEXT_TAGS "<sup>"; str += str_add; str += "</sup>" TEXT_TAGS_END;} else {str += TEXT_TAGS_SMALL; str += str_add; str += TEXT_TAGS_SMALL_END;}
  1298. #define STR_MARKUP_ADD(str, str_add) if(ips.power_depth > 0) {str += TEXT_TAGS "<sup>"; str += str_add; str += "</sup>" TEXT_TAGS_END;} else {str += str_add;}
  1299. #define STR_MARKUP_PREPEND(str, str_add) QString str_prepend; if(ips.power_depth > 0) {str_prepend += TEXT_TAGS "<sup>"; str_prepend += str_add; str_prepend += "</sup>" TEXT_TAGS_END;} else {str_prepend += str_add;} str.prepend(str_prepend);
  1300. #define STR_MARKUP_BEGIN(str) if(ips.power_depth > 0) {str += TEXT_TAGS "<sup>";}
  1301. #define STR_MARKUP_END(str) if(ips.power_depth > 0) {str +="</sup>" TEXT_TAGS_END;}
  1302. #define STR_MARKUP_BEGIN_SMALL(str) if(ips.power_depth > 0) {str += TEXT_TAGS_SMALL "<sup>";} else {str += TEXT_TAGS_SMALL;}
  1303. #define STR_MARKUP_END_SMALL(str) if(ips.power_depth > 0) {str +="</sup>" TEXT_TAGS_SMALL_END;} else {str += TEXT_TAGS_SMALL_END;}
  1304. #define STR_MARKUP_BEGIN_CURSIVE(str) if(ips.power_depth > 0) {str += TEXT_TAGS "<i><sup>";} else {str += "<i>";}
  1305. #define STR_MARKUP_END_CURSIVE(str) if(ips.power_depth > 0) {str +="</sup></i>" TEXT_TAGS_END;} else {str += "</i>";}
  1306. QString draw_structure(MathStructure &m, const QFont &font, const QColorGroup &cg, PrintOptions po = default_print_options, InternalPrintStruct ips = top_ips, bool in_matrix = false) {
  1307. if(ips.depth == 0 && po.is_approximate) *po.is_approximate = false;
  1308. QString mstr;
  1309. InternalPrintStruct ips_n = ips;
  1310. if(m.isApproximate()) ips_n.parent_approximate = true;
  1311. if(m.precision() > 0 && (ips_n.parent_precision < 1 || m.precision() < ips_n.parent_precision)) ips_n.parent_precision = m.precision();
  1312. switch(m.type()) {
  1313. case STRUCT_NUMBER: {
  1314. string exp = "";
  1315. bool exp_minus;
  1316. ips_n.exp = &exp;
  1317. ips_n.exp_minus = &exp_minus;
  1318. STR_MARKUP_BEGIN(mstr);
  1319. mstr += m.number().print(po, ips_n).c_str();
  1320. if(!exp.empty()) {
  1321. if(po.lower_case_e) {
  1322. mstr += "e";
  1323. } else {
  1324. STR_MARKUP_ADD_SMALL(mstr, "E");
  1325. }
  1326. if(exp_minus) {
  1327. mstr += "-";
  1328. }
  1329. mstr += exp.c_str();
  1330. }
  1331. if(po.base != BASE_DECIMAL && po.base != BASE_HEXADECIMAL && po.base > 0 && po.base <= 36) {
  1332. if(ips.power_depth == 0) {
  1333. mstr += "<sub>";
  1334. mstr += QString::number(po.base);
  1335. mstr += "</sub>";
  1336. } else {
  1337. mstr += TEXT_TAGS_SMALL "<sup>";
  1338. mstr += QString::number(po.base);
  1339. mstr += "</sup>" TEXT_TAGS_SMALL_END;
  1340. }
  1341. }
  1342. STR_MARKUP_END(mstr);
  1343. break;
  1344. }
  1345. case STRUCT_SYMBOLIC: {
  1346. result_parts.push_back(m);
  1347. mstr = "<a name=\"";
  1348. mstr += QString::number(result_parts.size());
  1349. mstr += "\">";
  1350. STR_MARKUP_BEGIN_CURSIVE(mstr);
  1351. mstr += m.symbol().c_str();
  1352. STR_MARKUP_END_CURSIVE(mstr);
  1353. mstr += "</a>";
  1354. mstr += "<a name=\"";
  1355. mstr += QString::number(result_parts.size());
  1356. mstr += "\"></a>";
  1357. break;
  1358. }
  1359. case STRUCT_ADDITION: {
  1360. ips_n.depth++;
  1361. vector<QString> terms;
  1362. vector<bool> do_space;
  1363. for(size_t i = 0; i < m.size(); i++) {
  1364. if(m[i].type() == STRUCT_NEGATE && i > 0) {
  1365. ips_n.wrap = m[i][0].needsParenthesis(po, ips_n, m, i + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1366. terms.push_back(draw_structure(m[i][0], font, cg, po, ips_n));
  1367. } else {
  1368. ips_n.wrap = m[i].needsParenthesis(po, ips_n, m, i + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1369. terms.push_back(draw_structure(m[i], font, cg, po, ips_n));
  1370. }
  1371. do_space.push_back(!terms[i].endsWith("valign=\"middle\">"));
  1372. }
  1373. for(size_t i = 0; i < terms.size(); i++) {
  1374. if(i > 0) {
  1375. if(do_space[i - 1]) STR_MARKUP_ADD(mstr, " ");
  1376. if(m[i].type() == STRUCT_NEGATE) {
  1377. if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_MINUS, po.can_display_unicode_string_arg))) {
  1378. STR_MARKUP_ADD(mstr, SIGN_MINUS);
  1379. } else {
  1380. STR_MARKUP_ADD(mstr, "-");
  1381. }
  1382. } else {
  1383. STR_MARKUP_ADD(mstr, "+");
  1384. }
  1385. if(do_space[i]) STR_MARKUP_ADD(mstr, " ");
  1386. }
  1387. mstr += terms[i];
  1388. }
  1389. break;
  1390. }
  1391. case STRUCT_NEGATE: {
  1392. ips_n.depth++;
  1393. ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1394. if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_MINUS, po.can_display_unicode_string_arg))) {
  1395. STR_MARKUP_ADD(mstr, SIGN_MINUS);
  1396. } else {
  1397. STR_MARKUP_ADD(mstr, "-");
  1398. }
  1399. mstr += draw_structure(m[0], font, cg, po, ips_n);
  1400. break;
  1401. }
  1402. case STRUCT_MULTIPLICATION: {
  1403. ips_n.depth++;
  1404. QString mul_str;
  1405. if(po.use_unicode_signs && po.multiplication_sign == MULTIPLICATION_SIGN_DOT && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_MULTIDOT, po.can_display_unicode_string_arg))) {
  1406. STR_MARKUP_ADD(mul_str, SIGN_MULTIDOT);
  1407. } else if(po.use_unicode_signs && po.multiplication_sign == MULTIPLICATION_SIGN_DOT && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_MULTIBULLET, po.can_display_unicode_string_arg))) {
  1408. STR_MARKUP_ADD(mul_str, SIGN_MULTIBULLET);
  1409. } else if(po.use_unicode_signs && po.multiplication_sign == MULTIPLICATION_SIGN_DOT && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_SMALLCIRCLE, po.can_display_unicode_string_arg))) {
  1410. STR_MARKUP_ADD(mul_str, SIGN_SMALLCIRCLE);
  1411. } else if(po.use_unicode_signs && po.multiplication_sign == MULTIPLICATION_SIGN_X && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_MULTIPLICATION, po.can_display_unicode_string_arg))) {
  1412. STR_MARKUP_ADD(mul_str, SIGN_MULTIPLICATION);
  1413. } else {
  1414. STR_MARKUP_ADD(mul_str, "*");
  1415. }
  1416. bool par_prev = false;
  1417. vector<int> nm;
  1418. vector<QString> terms;
  1419. vector<bool> do_space;
  1420. for(size_t i = 0; i < m.size(); i++) {
  1421. ips_n.wrap = m[i].needsParenthesis(po, ips_n, m, i + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1422. terms.push_back(draw_structure(m[i], font, cg, po, ips_n));
  1423. if(!po.short_multiplication && i > 0) {
  1424. nm.push_back(-1);
  1425. } else if(i > 0) {
  1426. nm.push_back(m[i].neededMultiplicationSign(po, ips_n, m, i + 1, ips_n.wrap || (m[i].isPower() && m[i][0].needsParenthesis(po, ips_n, m[i], 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0)), par_prev, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0));
  1427. } else {
  1428. nm.push_back(-1);
  1429. }
  1430. do_space.push_back(!terms[i].endsWith("valign=\"middle\">"));
  1431. par_prev = ips_n.wrap;
  1432. }
  1433. for(size_t i = 0; i < terms.size(); i++) {
  1434. if(!po.short_multiplication && i > 0) {
  1435. if(do_space[i - 1]) STR_MARKUP_ADD(mstr, " ");
  1436. mstr += mul_str;
  1437. if(do_space[i]) STR_MARKUP_ADD(mstr, " ");
  1438. } else if(i > 0) {
  1439. switch(nm[i]) {
  1440. case MULTIPLICATION_SIGN_SPACE: {
  1441. if(do_space[i - 1] && do_space[i]) STR_MARKUP_ADD(mstr, " ");
  1442. break;
  1443. }
  1444. case MULTIPLICATION_SIGN_OPERATOR: {
  1445. if(do_space[i - 1]) STR_MARKUP_ADD(mstr, " ");
  1446. mstr += mul_str;
  1447. if(do_space[i]) STR_MARKUP_ADD(mstr, " ");
  1448. break;
  1449. }
  1450. case MULTIPLICATION_SIGN_OPERATOR_SHORT: {
  1451. mstr += mul_str;
  1452. break;
  1453. }
  1454. }
  1455. }
  1456. mstr += terms[i];
  1457. }
  1458. break;
  1459. }
  1460. case STRUCT_INVERSE: {}
  1461. case STRUCT_DIVISION: {
  1462. ips_n.depth++;
  1463. ips_n.division_depth++;
  1464. bool flat = ips.division_depth > 0 || ips.power_depth > 0;
  1465. if(!flat && po.place_units_separately) {
  1466. flat = true;
  1467. size_t i = 0;
  1468. if(m.isDivision()) {
  1469. i = 1;
  1470. }
  1471. if(m[i].isMultiplication()) {
  1472. for(size_t i2 = 0; i2 < m[i].size(); i2++) {
  1473. if(!m[i][i2].isUnit_exp()) {
  1474. flat = false;
  1475. break;
  1476. }
  1477. }
  1478. } else if(!m[i].isUnit_exp()) {
  1479. flat = false;
  1480. }
  1481. if(flat) {
  1482. ips_n.division_depth--;
  1483. }
  1484. }
  1485. QString num_str, den_str;
  1486. if(m.type() == STRUCT_DIVISION) {
  1487. ips_n.wrap = (!m[0].isDivision() || !flat || ips.division_depth > 0 || ips.power_depth > 0) && m[0].needsParenthesis(po, ips_n, m, 1, flat, ips.power_depth > 0);
  1488. num_str = draw_structure(m[0], font, cg, po, ips_n);
  1489. } else {
  1490. MathStructure onestruct(1, 1);
  1491. ips_n.wrap = false;
  1492. num_str = draw_structure(onestruct, font, cg, po, ips_n);
  1493. }
  1494. if(m.type() == STRUCT_DIVISION) {
  1495. ips_n.wrap = m[1].needsParenthesis(po, ips_n, m, 2, flat, ips.power_depth > 0);
  1496. den_str = draw_structure(m[1], font, cg, po, ips_n);
  1497. } else {
  1498. ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 2, flat, ips.power_depth > 0);
  1499. den_str = draw_structure(m[0], font, cg, po, ips_n);
  1500. }
  1501. if(flat) {
  1502. QString div_str;
  1503. if(po.use_unicode_signs && po.division_sign == DIVISION_SIGN_DIVISION && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_DIVISION, po.can_display_unicode_string_arg))) {
  1504. STR_MARKUP_ADD(div_str, " " SIGN_DIVISION " ");
  1505. } else if(po.use_unicode_signs && po.division_sign == DIVISION_SIGN_DIVISION_SLASH && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_DIVISION_SLASH, po.can_display_unicode_string_arg))) {
  1506. STR_MARKUP_ADD(div_str, " " SIGN_DIVISION_SLASH " ");
  1507. } else {
  1508. STR_MARKUP_ADD(div_str, " / ");
  1509. }
  1510. mstr = num_str;
  1511. mstr += div_str;
  1512. mstr += den_str;
  1513. } else {
  1514. int den_w, num_w, w = 0, h = 0;
  1515. num_str.prepend(TEXT_TAGS);
  1516. num_str += TEXT_TAGS_END;
  1517. den_str.prepend(TEXT_TAGS);
  1518. den_str += TEXT_TAGS_END;
  1519. QSimpleRichText text_r(num_str, font); text_r.setWidth(10000);
  1520. num_w = text_r.widthUsed();
  1521. QSimpleRichText text_rn(den_str, font); text_rn.setWidth(10000);
  1522. den_w = text_rn.widthUsed();
  1523. w = den_w;
  1524. if(num_w > w) w = num_w;
  1525. w += 2;
  1526. QSimpleRichText textsmall("<font size=\"1\">X</font>", font);
  1527. h = (int) (textsmall.height() / 1.5);
  1528. h += h % 2;
  1529. string filename = getLocalDir();
  1530. if(saved_divisionline_height != h) {
  1531. QPixmap *pixmap = new QPixmap(10, h);
  1532. pixmap->fill(cg.background());
  1533. QPainter p(pixmap);
  1534. QPen ppen = p.pen();
  1535. ppen.setColor(cg.foreground());
  1536. p.setPen(ppen);
  1537. p.drawLine(0, h / 2, 10, h / 2);
  1538. p.drawLine(0, h / 2 + 1, 10, h / 2 + 1);
  1539. p.flush();
  1540. p.end();
  1541. pixmap->setMask(pixmap->createHeuristicMask());
  1542. mkdir(filename.c_str(), S_IRWXU);
  1543. filename += "tmp/";
  1544. mkdir(filename.c_str(), S_IRWXU);
  1545. filename += "divline.png";
  1546. pixmap->save(filename.c_str(), "PNG", 100);
  1547. delete pixmap;
  1548. saved_divisionline_height = h;
  1549. } else {
  1550. filename += "tmp/divline.png";
  1551. }
  1552. mstr = TEXT_TAGS_END;
  1553. mstr = "</td><td width=1 align=\"center\" valign=\"middle\">";
  1554. mstr += num_str;
  1555. mstr += "<br><font size=1><img align=\"middle\" width=";
  1556. mstr += QString::number(w);
  1557. mstr += " height=";
  1558. mstr += QString::number(h);
  1559. mstr += " src=\"";
  1560. mstr += filename.c_str();
  1561. mstr += "\"><br></font>";
  1562. mstr += den_str;
  1563. mstr += "</td><td width=1 align=\"center\" valign=\"middle\">";
  1564. mstr += TEXT_TAGS;
  1565. }
  1566. break;
  1567. }
  1568. case STRUCT_POWER: {
  1569. ips_n.depth++;
  1570. ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1571. ips_n.division_depth++;
  1572. mstr += draw_structure(m[0], font, cg, po, ips_n);
  1573. ips_n.division_depth--;
  1574. ips_n.power_depth++;
  1575. ips_n.wrap = m[1].needsParenthesis(po, ips_n, m, 2, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1576. PrintOptions po2 = po;
  1577. po2.show_ending_zeroes = false;
  1578. if(ips.power_depth > 0) {
  1579. mstr += TEXT_TAGS "<sup>" "^" "</sup>" TEXT_TAGS_END;
  1580. mstr += draw_structure(m[1], font, cg, po2, ips_n);
  1581. } else {
  1582. mstr += draw_structure(m[1], font, cg, po2, ips_n);
  1583. }
  1584. break;
  1585. }
  1586. case STRUCT_LOGICAL_AND: {
  1587. if(!po.preserve_format && m.size() == 2 && m[0].isComparison() && m[1].isComparison() && m[0].comparisonType() != COMPARISON_EQUALS && m[0].comparisonType() != COMPARISON_NOT_EQUALS && m[1].comparisonType() != COMPARISON_EQUALS && m[1].comparisonType() != COMPARISON_NOT_EQUALS && m[0][0] == m[1][0]) {
  1588. ips_n.depth++;
  1589. bool do_space = true;
  1590. QString tstr;
  1591. ips_n.wrap = m[0][1].needsParenthesis(po, ips_n, m[0], 2, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1592. tstr = draw_structure(m[0][1], font, cg, po, ips_n);
  1593. do_space = !tstr.endsWith("valign=\"middle\">");
  1594. mstr += tstr;
  1595. STR_MARKUP_BEGIN(mstr);
  1596. if(do_space) mstr += " ";
  1597. switch(m[0].comparisonType()) {
  1598. case COMPARISON_LESS: {
  1599. mstr += "&gt;";
  1600. break;
  1601. }
  1602. case COMPARISON_GREATER: {
  1603. mstr += "&lt;";
  1604. break;
  1605. }
  1606. case COMPARISON_EQUALS_LESS: {
  1607. if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_GREATER_OR_EQUAL, po.can_display_unicode_string_arg))) {
  1608. mstr += SIGN_GREATER_OR_EQUAL;
  1609. } else {
  1610. mstr += "&gt;=";
  1611. }
  1612. break;
  1613. }
  1614. case COMPARISON_EQUALS_GREATER: {
  1615. if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_LESS_OR_EQUAL, po.can_display_unicode_string_arg))) {
  1616. mstr += SIGN_LESS_OR_EQUAL;
  1617. } else {
  1618. mstr += "&lt;=";
  1619. }
  1620. break;
  1621. }
  1622. default: {}
  1623. }
  1624. ips_n.wrap = m[0][0].needsParenthesis(po, ips_n, m[0], 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1625. tstr = draw_structure(m[0][0], font, cg, po, ips_n);
  1626. do_space = !tstr.endsWith("valign=\"middle\">");
  1627. if(do_space) mstr += " ";
  1628. STR_MARKUP_END(mstr);
  1629. mstr += tstr;
  1630. STR_MARKUP_BEGIN(mstr);
  1631. if(do_space) mstr += " ";
  1632. switch(m[1].comparisonType()) {
  1633. case COMPARISON_GREATER: {
  1634. mstr += "&gt;";
  1635. break;
  1636. }
  1637. case COMPARISON_LESS: {
  1638. mstr += "&lt;";
  1639. break;
  1640. }
  1641. case COMPARISON_EQUALS_GREATER: {
  1642. if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_GREATER_OR_EQUAL, po.can_display_unicode_string_arg))) {
  1643. mstr += SIGN_GREATER_OR_EQUAL;
  1644. } else {
  1645. mstr += "&gt;=";
  1646. }
  1647. break;
  1648. }
  1649. case COMPARISON_EQUALS_LESS: {
  1650. if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_LESS_OR_EQUAL, po.can_display_unicode_string_arg))) {
  1651. mstr += SIGN_LESS_OR_EQUAL;
  1652. } else {
  1653. mstr += "&lt;=";
  1654. }
  1655. break;
  1656. }
  1657. default: {}
  1658. }
  1659. ips_n.wrap = m[1][1].needsParenthesis(po, ips_n, m[1], 2, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1660. tstr = draw_structure(m[1][1], font, cg, po, ips_n);
  1661. do_space = !tstr.endsWith("valign=\"middle\">");
  1662. if(do_space) mstr += " ";
  1663. STR_MARKUP_END(mstr);
  1664. mstr += tstr;
  1665. break;
  1666. }
  1667. }
  1668. case STRUCT_COMPARISON: {}
  1669. case STRUCT_LOGICAL_XOR: {}
  1670. case STRUCT_LOGICAL_OR: {}
  1671. case STRUCT_BITWISE_AND: {}
  1672. case STRUCT_BITWISE_XOR: {}
  1673. case STRUCT_BITWISE_OR: {
  1674. ips_n.depth++;
  1675. QString str;
  1676. if(m.type() == STRUCT_COMPARISON) {
  1677. switch(m.comparisonType()) {
  1678. case COMPARISON_EQUALS: {
  1679. break;
  1680. }
  1681. case COMPARISON_NOT_EQUALS: {
  1682. if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_NOT_EQUAL, po.can_display_unicode_string_arg))) {
  1683. str += SIGN_NOT_EQUAL;
  1684. } else {
  1685. str += "!=";
  1686. }
  1687. break;
  1688. }
  1689. case COMPARISON_GREATER: {
  1690. str += "&gt;";
  1691. break;
  1692. }
  1693. case COMPARISON_LESS: {
  1694. str += "&lt;";
  1695. break;
  1696. }
  1697. case COMPARISON_EQUALS_GREATER: {
  1698. if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_GREATER_OR_EQUAL, po.can_display_unicode_string_arg))) {
  1699. str += SIGN_GREATER_OR_EQUAL;
  1700. } else {
  1701. str += "&gt;=";
  1702. }
  1703. break;
  1704. }
  1705. case COMPARISON_EQUALS_LESS: {
  1706. if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_LESS_OR_EQUAL, po.can_display_unicode_string_arg))) {
  1707. str += SIGN_LESS_OR_EQUAL;
  1708. } else {
  1709. str += "&lt;=";
  1710. }
  1711. break;
  1712. }
  1713. }
  1714. } else if(m.type() == STRUCT_LOGICAL_AND) {
  1715. str += "<a name=\"+Logical AND\">";
  1716. if(po.spell_out_logical_operators) str += i18n("and");
  1717. else str += "&amp;&amp;";
  1718. str += "</a>";
  1719. } else if(m.type() == STRUCT_LOGICAL_OR) {
  1720. str += "<a name=\"+Logical inclusive OR\">";
  1721. if(po.spell_out_logical_operators) str += i18n("or");
  1722. else str += "||";
  1723. str += "</a>";
  1724. } else if(m.type() == STRUCT_LOGICAL_XOR) {
  1725. str += "<a name=\"+Logical exclusive OR\">XOR</a>";
  1726. } else if(m.type() == STRUCT_BITWISE_AND) {
  1727. str += "<a name=\"+Bitwise AND\">&amp;</a>";
  1728. } else if(m.type() == STRUCT_BITWISE_OR) {
  1729. str += "<a name=\"+Bitwise inclusive OR\">|</a>";
  1730. } else if(m.type() == STRUCT_BITWISE_XOR) {
  1731. str += "<a name=\"+Bitwise exclusive XOR\">XOR</a>";
  1732. }
  1733. bool do_space = true, do_space_prev = true;
  1734. QString tstr;
  1735. for(size_t i = 0; i < m.size(); i++) {
  1736. do_space_prev = do_space;
  1737. ips_n.wrap = m[i].needsParenthesis(po, ips_n, m, i + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1738. tstr = draw_structure(m[i], font, cg, po, ips_n);
  1739. do_space = !tstr.endsWith("valign=\"middle\">");
  1740. if(i > 0) {
  1741. STR_MARKUP_BEGIN(mstr);
  1742. if(do_space_prev) mstr += " ";
  1743. if(m.isComparison() && m.comparisonType() == COMPARISON_EQUALS) {
  1744. if(ips.depth == 0 && po.use_unicode_signs && (*po.is_approximate || m.isApproximate()) && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_ALMOST_EQUAL, po.can_display_unicode_string_arg))) {
  1745. mstr += SIGN_ALMOST_EQUAL;
  1746. } else {
  1747. mstr += "=";
  1748. }
  1749. } else {
  1750. mstr += str;
  1751. }
  1752. if(do_space) mstr += " ";
  1753. STR_MARKUP_END(mstr);
  1754. }
  1755. mstr += tstr;
  1756. }
  1757. break;
  1758. }
  1759. case STRUCT_BITWISE_NOT: {
  1760. ips_n.depth++;
  1761. STR_MARKUP_BEGIN(mstr);
  1762. mstr += "<a name=\"+Bitwise NOT\">~</a>";
  1763. ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1764. mstr += draw_structure(m[0], font, cg, po, ips_n);
  1765. STR_MARKUP_END(mstr);
  1766. break;
  1767. }
  1768. case STRUCT_LOGICAL_NOT: {
  1769. ips_n.depth++;
  1770. STR_MARKUP_BEGIN(mstr);
  1771. mstr += "<a name=\"+Logical NOT\">!</a>";
  1772. ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1773. mstr += draw_structure(m[0], font, cg, po, ips_n);
  1774. STR_MARKUP_END(mstr);
  1775. break;
  1776. }
  1777. case STRUCT_VECTOR: {
  1778. ips_n.depth++;
  1779. bool is_matrix = m.isMatrix();
  1780. if(!in_matrix) {
  1781. result_parts.push_back(m);
  1782. mstr = "<a name=\"";
  1783. mstr += QString::number(result_parts.size());
  1784. mstr += "\">";
  1785. }
  1786. if(m.size() == 0) {
  1787. STR_MARKUP_ADD(mstr, "( ");
  1788. } else {
  1789. STR_MARKUP_ADD(mstr, "(");
  1790. }
  1791. for(size_t index = 0; index < m.size(); index++) {
  1792. if(index > 0) {
  1793. STR_MARKUP_BEGIN(mstr);
  1794. mstr += CALCULATOR->getComma().c_str();
  1795. mstr += " ";
  1796. STR_MARKUP_END(mstr);
  1797. }
  1798. ips_n.wrap = m[index].needsParenthesis(po, ips_n, m, index + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
  1799. mstr += draw_structure(m[index], font, cg, po, ips_n, is_matrix);
  1800. }
  1801. STR_MARKUP_ADD(mstr, ")");
  1802. if(!in_matrix) mstr += "</a>";
  1803. break;
  1804. }
  1805. case STRUCT_UNIT: {
  1806. result_parts.push_back(m);
  1807. mstr = "<a name=\"";
  1808. mstr += QString::number(result_parts.size());
  1809. mstr += "\">";
  1810. STR_MARKUP_BEGIN(mstr);
  1811. QString str;
  1812. const ExpressionName *ename = &m.unit()->preferredDisplayName(po.abbreviate_names, po.use_unicode_signs, m.isPlural(), po.use_reference_names, po.can_display_unicode_string_function, po.can_display_unicode_string_arg);
  1813. if(m.prefix()) {
  1814. str += m.prefix()->name(po.abbreviate_names && ename->abbreviation && (ename->suffix || ename->name.find("_") == string::npos), po.use_unicode_signs, po.can_display_unicode_string_function, po.can_display_unicode_string_arg).c_str();
  1815. }
  1816. if(ename->suffix && ename->name.length() > 1) {
  1817. size_t i = ename->name.rfind('_');
  1818. bool b = i == string::npos || i == ename->name.length() - 1 || i == 0;
  1819. size_t i2 = 1;
  1820. if(b) {
  1821. if(is_in(NUMBERS, ename->name[ename->name.length() - 1])) {
  1822. while(ename->name.length() > i2 + 1 && is_in(NUMBERS, ename->name[ename->name.length() - 1 - i2])) {
  1823. i2++;
  1824. }
  1825. }
  1826. str += ename->name.substr(0, ename->name.length() - i2).c_str();
  1827. } else {
  1828. str += ename->name.substr(0, i).c_str();
  1829. }
  1830. if(ips.power_depth == 0) str += "<sub>";
  1831. else str += TEXT_TAGS_SMALL "<sup>";
  1832. if(b) str += ename->name.substr(ename->name.length() - i2, i2).c_str();
  1833. else str += ename->name.substr(i + 1, ename->name.length() - (i + 1)).c_str();
  1834. if(ips.power_depth == 0) str += "</sub>";
  1835. else str += "</sup>" TEXT_TAGS_SMALL_END;
  1836. } else {
  1837. str += ename->name.c_str();
  1838. }
  1839. str.replace("_", " ");
  1840. mstr += str;
  1841. STR_MARKUP_END(mstr);
  1842. mstr += "</a>";
  1843. mstr += "<a name=\"";
  1844. mstr += QString::number(result_parts.size());
  1845. mstr += "\"></a>";
  1846. break;
  1847. }
  1848. case STRUCT_VARIABLE: {
  1849. result_parts.push_back(m);
  1850. mstr = "<a name=\"";
  1851. mstr += QString::number(result_parts.size());
  1852. mstr += "\">";
  1853. if(m.variable() == CALCULATOR->v_i) {
  1854. STR_MARKUP_BEGIN(mstr);
  1855. } else {
  1856. STR_MARKUP_BEGIN_CURSIVE(mstr);
  1857. }
  1858. QString str;
  1859. const ExpressionName *ename = &m.variable()->preferredDisplayName(po.abbreviate_names, po.use_unicode_signs, false, po.use_reference_names, po.can_display_unicode_string_function, po.can_display_unicode_string_arg);
  1860. if(ename->suffix && ename->name.length() > 1) {
  1861. size_t i = ename->name.rfind('_');
  1862. bool b = i == string::npos || i == ename->name.length() - 1 || i == 0;
  1863. size_t i2 = 1;
  1864. if(b) {
  1865. if(is_in(NUMBERS, ename->name[ename->name.length() - 1])) {
  1866. while(ename->name.length() > i2 + 1 && is_in(NUMBERS, ename->name[ename->name.length() - 1 - i2])) {
  1867. i2++;
  1868. }
  1869. }
  1870. str += ename->name.substr(0, ename->name.length() - i2).c_str();
  1871. } else {
  1872. str += ename->name.substr(0, i).c_str();
  1873. }
  1874. if(ips.power_depth == 0) str += "<sub>";
  1875. else str += TEXT_TAGS_SMALL "<sup>";
  1876. if(b) str += ename->name.substr(ename->name.length() - i2, i2).c_str();
  1877. else str += ename->name.substr(i + 1, ename->name.length() - (i + 1)).c_str();
  1878. if(ips.power_depth == 0) str += "</sub>";
  1879. else str += "</sup>" TEXT_TAGS_SMALL_END;
  1880. } else {
  1881. str += ename->name.c_str();
  1882. }
  1883. str.replace("_", " ");
  1884. mstr += str;
  1885. if(m.variable() == CALCULATOR->v_i) {
  1886. STR_MARKUP_END(mstr);
  1887. } else {
  1888. STR_MARKUP_END_CURSIVE(mstr);
  1889. }
  1890. mstr += "</a>";
  1891. /*result_parts.push_back(m);
  1892. mstr += "<a name=\"";
  1893. mstr += QString::number(result_parts.size());
  1894. mstr += "\"></a>";*/
  1895. break;
  1896. }
  1897. case STRUCT_FUNCTION: {
  1898. ips_n.depth++;
  1899. result_parts.push_back(m);
  1900. mstr = "<a name=\"";
  1901. mstr += QString::number(result_parts.size());
  1902. mstr += "\">";
  1903. STR_MARKUP_BEGIN(mstr);
  1904. QString str;
  1905. const ExpressionName *ename = &m.function()->preferredDisplayName(po.abbreviate_names, po.use_unicode_signs, false, po.use_reference_names, po.can_display_unicode_string_function, po.can_display_unicode_string_arg);
  1906. if(ename->suffix && ename->name.length() > 1) {
  1907. size_t i = ename->name.rfind('_');
  1908. bool b = i == string::npos || i == ename->name.length() - 1 || i == 0;
  1909. size_t i2 = 1;
  1910. if(b) {
  1911. if(is_in(NUMBERS, ename->name[ename->name.length() - 1])) {
  1912. while(ename->name.length() > i2 + 1 && is_in(NUMBERS, ename->name[ename->name.length() - 1 - i2])) {
  1913. i2++;
  1914. }
  1915. }
  1916. str += ename->name.substr(0, ename->name.length() - i2).c_str();
  1917. } else {
  1918. str += ename->name.substr(0, i).c_str();
  1919. }
  1920. if(ips.power_depth == 0) str += "<sub>";
  1921. else str += TEXT_TAGS_SMALL "<sup>";
  1922. if(b) str += ename->name.substr(ename->name.length() - i2, i2).c_str();
  1923. else str += ename->name.substr(i + 1, ename->name.length() - (i + 1)).c_str();
  1924. if(ips.power_depth == 0) str += "</sub>";
  1925. else str += "</sup>" TEXT_TAGS_SMALL_END;
  1926. } else {
  1927. str += ename->name.c_str();
  1928. }
  1929. str.replace("_", " ");
  1930. mstr += str;
  1931. mstr += "(";
  1932. STR_MARKUP_END(mstr);
  1933. mstr += "</a>";
  1934. for(size_t index = 0; index < m.size(); index++) {
  1935. if(index > 0) {
  1936. STR_MARKUP_BEGIN(mstr);
  1937. mstr += po.comma().c_str();
  1938. mstr += " ";
  1939. STR_MARKUP_END(mstr);
  1940. }
  1941. mstr += draw_structure(m[index], font, cg, po, ips_n);
  1942. }
  1943. STR_MARKUP_ADD(mstr, ")");
  1944. break;
  1945. }
  1946. case STRUCT_UNDEFINED: {
  1947. STR_MARKUP_ADD(mstr, i18n("undefined"));
  1948. break;
  1949. }
  1950. default: {
  1951. }
  1952. }
  1953. if(ips.wrap) {
  1954. STR_MARKUP_PREPEND(mstr, "(");
  1955. STR_MARKUP_ADD(mstr, ")");
  1956. }
  1957. if(ips.depth == 0 && !(m.isComparison() && (!(*po.is_approximate || m.isApproximate()) || (m.comparisonType() == COMPARISON_EQUALS && po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_ALMOST_EQUAL, po.can_display_unicode_string_arg)))))) {
  1958. QString equals_str;
  1959. if(*po.is_approximate || m.isApproximate()) {
  1960. if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_ALMOST_EQUAL, po.can_display_unicode_string_arg))) {
  1961. equals_str = SIGN_ALMOST_EQUAL " ";
  1962. } else {
  1963. equals_str += i18n("approx.");
  1964. equals_str += " ";
  1965. }
  1966. } else {
  1967. equals_str = "= ";
  1968. }
  1969. mstr.prepend(equals_str);
  1970. }
  1971. if(ips.depth == 0) {
  1972. mstr.prepend(TEXT_TAGS);
  1973. mstr += TEXT_TAGS_END;
  1974. }
  1975. return mstr;
  1976. }
  1977. #define STATUS_SPACE if(b) str += " "; else b = true;
  1978. void KQalculate::update_status_text() {
  1979. QString str;
  1980. bool b = false;
  1981. if(evalops.approximation == APPROXIMATION_EXACT) {
  1982. STATUS_SPACE
  1983. str += i18n("EXACT");
  1984. } else if(evalops.approximation == APPROXIMATION_APPROXIMATE) {
  1985. STATUS_SPACE
  1986. str += i18n("APPROX");
  1987. }
  1988. if(evalops.parse_options.rpn) {
  1989. STATUS_SPACE
  1990. str += i18n("RPN");
  1991. }
  1992. switch(evalops.parse_options.base) {
  1993. case BASE_DECIMAL: {
  1994. break;
  1995. }
  1996. case BASE_BINARY: {
  1997. STATUS_SPACE
  1998. str += i18n("BIN");
  1999. break;
  2000. }
  2001. case BASE_OCTAL: {
  2002. STATUS_SPACE
  2003. str += i18n("OCT");
  2004. break;
  2005. }
  2006. case BASE_HEXADECIMAL: {
  2007. STATUS_SPACE
  2008. str += i18n("HEX");
  2009. break;
  2010. }
  2011. case BASE_ROMAN_NUMERALS: {
  2012. STATUS_SPACE
  2013. str += i18n("ROMAN");
  2014. break;
  2015. }
  2016. default: {
  2017. STATUS_SPACE
  2018. str += QString::number(evalops.parse_options.base);
  2019. break;
  2020. }
  2021. }
  2022. switch (evalops.parse_options.angle_unit) {
  2023. case ANGLE_UNIT_DEGREES: {
  2024. STATUS_SPACE
  2025. str += i18n("DEG");
  2026. break;
  2027. }
  2028. case ANGLE_UNIT_RADIANS: {
  2029. STATUS_SPACE
  2030. str += i18n("RAD");
  2031. break;
  2032. }
  2033. case ANGLE_UNIT_GRADIANS: {
  2034. STATUS_SPACE
  2035. str += i18n("GRA");
  2036. break;
  2037. }
  2038. default: {}
  2039. }
  2040. if(evalops.parse_options.read_precision != DONT_READ_PRECISION) {
  2041. STATUS_SPACE
  2042. str += i18n("PREC");
  2043. }
  2044. if(!evalops.parse_options.functions_enabled) {
  2045. STATUS_SPACE
  2046. str += "<s>";
  2047. str += i18n("FUNC");
  2048. str += "</s>";
  2049. }
  2050. if(!evalops.parse_options.units_enabled) {
  2051. STATUS_SPACE
  2052. str += "<s>";
  2053. str += i18n("UNIT");
  2054. str += "</s>";
  2055. }
  2056. if(!evalops.parse_options.variables_enabled) {
  2057. STATUS_SPACE
  2058. str += "<s>";
  2059. str += i18n("VAR");
  2060. str += "</s>";
  2061. }
  2062. if(!evalops.allow_infinite) {
  2063. STATUS_SPACE
  2064. str += "<s>";
  2065. str += i18n("INF");
  2066. str += "</s>";
  2067. }
  2068. if(!evalops.allow_complex) {
  2069. STATUS_SPACE
  2070. str += "<s>";
  2071. str += i18n("CPLX");
  2072. str += "</s>";
  2073. }
  2074. str = str.stripWhiteSpace();
  2075. if(b) str += "&nbsp;";
  2076. else str += "&nbsp;&nbsp;";
  2077. if(str != statusLabel_r->text()) {
  2078. statusLabel_r->setText(str);
  2079. qApp->processEvents();
  2080. displayParseStatus();
  2081. }
  2082. }
  2083. void on_abort_display() {
  2084. pthread_cancel(view_thread);
  2085. CALCULATOR->restoreState();
  2086. CALCULATOR->clearBuffers();
  2087. b_busy = false;
  2088. pthread_create(&view_thread, &view_thread_attr, view_proc, view_pipe_r);
  2089. }
  2090. void *view_proc(void *pipe) {
  2091. pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
  2092. pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  2093. FILE *view_pipe = (FILE*) pipe;
  2094. while(true) {
  2095. bool *do_wrap;
  2096. void *x = NULL;
  2097. fread(&x, sizeof(void*), 1, view_pipe);
  2098. KQalculate *win = (KQalculate*) x;
  2099. fread(&x, sizeof(void*), 1, view_pipe);
  2100. MathStructure m(*((MathStructure*) x));
  2101. fread(&x, sizeof(void*), 1, view_pipe);
  2102. MathStructure *mm = (MathStructure*) x;
  2103. fread(&do_wrap, sizeof(bool*), 1, view_pipe);
  2104. fread(&x, sizeof(void*), 1, view_pipe);
  2105. printops.can_display_unicode_string_arg = (void*) win->historyBrowser;
  2106. if(x) {
  2107. PrintOptions po;
  2108. po.preserve_format = true;
  2109. po.show_ending_zeroes = true;
  2110. po.lower_case_e = printops.lower_case_e;
  2111. po.lower_case_numbers = printops.lower_case_numbers;
  2112. po.base_display = printops.base_display;
  2113. po.abbreviate_names = false;
  2114. po.use_unicode_signs = printops.use_unicode_signs;
  2115. po.multiplication_sign = printops.multiplication_sign;
  2116. po.division_sign = printops.division_sign;
  2117. po.short_multiplication = false;
  2118. po.excessive_parenthesis = true;
  2119. po.improve_division_multipliers = false;
  2120. po.can_display_unicode_string_function = &can_display_unicode_string_function;
  2121. po.can_display_unicode_string_arg = (void*) win->statusLabel_l;
  2122. po.spell_out_logical_operators = printops.spell_out_logical_operators;
  2123. po.restrict_to_parent_precision = false;
  2124. MathStructure mp(*((MathStructure*) x));
  2125. fread(&po.is_approximate, sizeof(bool*), 1, view_pipe);
  2126. mp.format(po);
  2127. parsed_text = mp.print(po).c_str();
  2128. fread(&x, sizeof(void*), 1, view_pipe);
  2129. mp.set(*((MathStructure*) x));
  2130. if(!mp.isUndefined()) {
  2131. mp.format(po);
  2132. parsed_text += CALCULATOR->localToString().c_str();
  2133. parsed_text += mp.print(po).c_str();
  2134. }
  2135. }
  2136. printops.allow_non_usable = false;
  2137. if(mm && m.isMatrix()) {
  2138. mm->set(m);
  2139. MathStructure mm2(m);
  2140. string mstr;
  2141. int c = mm->columns(), r = mm->rows();
  2142. for(int index_r = 0; index_r < r; index_r++) {
  2143. for(int index_c = 0; index_c < c; index_c++) {
  2144. mm->getElement(index_r + 1, index_c + 1)->set(i18n("aborted").ascii());
  2145. }
  2146. }
  2147. for(int index_r = 0; index_r < r; index_r++) {
  2148. for(int index_c = 0; index_c < c; index_c++) {
  2149. mm2.getElement(index_r + 1, index_c + 1)->format(printops);
  2150. mstr = mm2.getElement(index_r + 1, index_c + 1)->print(printops);
  2151. mm->getElement(index_r + 1, index_c + 1)->set(mstr);
  2152. }
  2153. }
  2154. }
  2155. m.format(printops);
  2156. result_history_text = m.print(printops).c_str();
  2157. printops.can_display_unicode_string_arg = NULL;
  2158. /*if(result_history_text.length() > 5000) {
  2159. result_text = i18n("result is too long\nsee history");
  2160. *printops.is_approximate = false;
  2161. } else */
  2162. if(mm && result_text == i18n("aborted")) {
  2163. result_text = i18n("calculation was aborted");
  2164. *printops.is_approximate = false;
  2165. } else if(mm) {
  2166. printops.allow_non_usable = true;
  2167. printops.can_display_unicode_string_arg = (void*) win->resultLabel;
  2168. QFont font(win->resultLabel->font());
  2169. result_text = draw_structure(m, font, win->resultLabel->colorGroup(), printops);
  2170. if(result_text.find("</td>") >= 0) {
  2171. result_text.prepend("<div align=\"right\"><table width=1 cellspacing=0 cellpadding=0 border=0><tr><td width=1 align=\"center\" valign=\"middle\">");
  2172. result_text += "</td></tr></table></div>";
  2173. *do_wrap = false;
  2174. } else {
  2175. result_text.prepend("<div align=\"right\"><font size=2>&nbsp;<br></font>");
  2176. result_text += "</div>";
  2177. *do_wrap = true;
  2178. }
  2179. printops.can_display_unicode_string_arg = NULL;
  2180. printops.allow_non_usable = false;
  2181. }
  2182. b_busy = false;
  2183. }
  2184. return NULL;
  2185. }
  2186. void KQalculate::clearresult() {
  2187. resultLabel->setRightMargin(10);
  2188. resultLabel->setText("<font size=6> </font>");
  2189. parsed_text = "";
  2190. result_parts.clear();
  2191. }
  2192. void reduceDivLineSize(QalculateResultDisplay *resultLabel) {
  2193. QString str = result_text;
  2194. QColorGroup cg = resultLabel->colorGroup();
  2195. int rt_i = 0;
  2196. while(true) {
  2197. int i2 = str.find("</td><td width=1 align=\"center\" valign=\"middle\">", 0);
  2198. if(i2 < 0) break;
  2199. str.remove(0, i2 + 48);
  2200. rt_i += i2 + 48;
  2201. i2 = str.find("<br>", 0);
  2202. if(i2 < 0) break;
  2203. int width_i = rt_i + i2 + 43;
  2204. QString num_str = str;
  2205. num_str.truncate(i2);
  2206. i2 = str.find("<br>", i2 + 4);
  2207. if(i2 < 0) break;
  2208. str.remove(0, i2 + 11);
  2209. rt_i += i2 + 11;
  2210. i2 = str.find("</td><td width=1 align=\"center\" valign=\"middle\">", 0);
  2211. if(i2 < 0) break;
  2212. QString den_str = str;
  2213. den_str.truncate(i2);
  2214. str.remove(0, i2 + 48);
  2215. rt_i += i2 + 48;
  2216. int den_w, num_w, w = 0, h = 0;
  2217. QSimpleRichText text_r(num_str, resultLabel->font()); text_r.setWidth(10000);
  2218. num_w = text_r.widthUsed();
  2219. QSimpleRichText text_rn(den_str, resultLabel->font()); text_rn.setWidth(10000);
  2220. den_w = text_rn.widthUsed();
  2221. w = den_w;
  2222. if(num_w > w) w = num_w;
  2223. w += 2;
  2224. QSimpleRichText textsmall("<font size=\"1\">X</font>", resultLabel->font());
  2225. h = (int) (textsmall.height() / 1.5);
  2226. h += h % 2;
  2227. string filename = getLocalDir();
  2228. if(saved_divisionline_height != h) {
  2229. QPixmap *pixmap = new QPixmap(10, h);
  2230. pixmap->fill(cg.background());
  2231. QPainter p(pixmap);
  2232. QPen ppen = p.pen();
  2233. ppen.setColor(cg.foreground());
  2234. p.setPen(ppen);
  2235. p.drawLine(0, h / 2, 10, h / 2);
  2236. p.drawLine(0, h / 2 + 1, 10, h / 2 + 1);
  2237. p.flush();
  2238. p.end();
  2239. pixmap->setMask(pixmap->createHeuristicMask());
  2240. mkdir(filename.c_str(), S_IRWXU);
  2241. filename += "tmp/";
  2242. mkdir(filename.c_str(), S_IRWXU);
  2243. filename += "divline.png";
  2244. pixmap->save(filename.c_str(), "PNG", 100);
  2245. delete pixmap;
  2246. saved_divisionline_height = h;
  2247. } else {
  2248. filename += "tmp/divline.png";
  2249. }
  2250. int height_i = result_text.find(" height=", width_i);
  2251. if(height_i < 0) break;
  2252. num_str = QString::number(w);
  2253. result_text.replace(width_i, height_i - width_i, num_str);
  2254. int i_diff = num_str.length() - (height_i - width_i);
  2255. rt_i += i_diff;
  2256. height_i += i_diff;
  2257. height_i += 8;
  2258. int height_i_end = result_text.find(" src=", height_i);
  2259. if(height_i_end < 0) break;
  2260. num_str = QString::number(h);
  2261. result_text.replace(height_i, height_i_end - height_i, num_str);
  2262. i_diff = num_str.length() - (height_i_end - height_i);
  2263. rt_i += i_diff;
  2264. }
  2265. }
  2266. Prefix *set_result_prefix;
  2267. bool set_result_update_history;
  2268. bool set_result_update_parse;
  2269. bool set_result_force;
  2270. QString set_result_transformation;
  2271. size_t set_result_stack_index;
  2272. bool set_result_register_moved;
  2273. void KQalculate::setResult(Prefix *prefix, bool update_history, bool update_parse, bool force, QString transformation, size_t stack_index, bool register_moved) {
  2274. if(expression_has_changed && !rpn_mode) {
  2275. if(!force) return;
  2276. execute_expression();
  2277. if(!prefix) return;
  2278. }
  2279. set_result_prefix = prefix;
  2280. set_result_update_history = update_history;
  2281. set_result_update_parse = update_parse;
  2282. set_result_force = force;
  2283. set_result_transformation = transformation;
  2284. set_result_stack_index = stack_index;
  2285. set_result_register_moved = register_moved;
  2286. QTimer::singleShot(0, this, SLOT(setResult2()));
  2287. }
  2288. void KQalculate::setResult2() {
  2289. if(block_result_update) return;
  2290. Prefix *prefix = set_result_prefix;
  2291. bool update_history = set_result_update_history;
  2292. bool update_parse = set_result_update_parse;
  2293. bool force = set_result_force;
  2294. bool register_moved = set_result_register_moved;
  2295. QString transformation = set_result_transformation;
  2296. size_t stack_index = set_result_stack_index;
  2297. if(!rpn_mode) stack_index = 0;
  2298. if(stack_index != 0) {
  2299. update_history = true;
  2300. update_parse = false;
  2301. }
  2302. if(register_moved) {
  2303. update_history = true;
  2304. update_parse = false;
  2305. }
  2306. error_timer->stop();
  2307. b_busy = true;
  2308. uint history_index = 0;
  2309. int inhistory_index = 0;
  2310. if(update_history) {
  2311. if(update_parse || register_moved) {
  2312. QString text;
  2313. if(register_moved) {
  2314. text = i18n("RPN Register Moved");
  2315. inhistory.insert(inhistory.begin(), QString::null);
  2316. inhistory_type.insert(inhistory_type.begin(), QALCULATE_HISTORY_REGISTER_MOVED);
  2317. inhistory_id.insert(inhistory_id.begin(), inhistory_current_id);
  2318. inhistory_current_id++;
  2319. inhistory_index++;
  2320. } else {
  2321. QString text2 = result_history_text;
  2322. text2.replace("&", "&amp;");
  2323. text2.replace(">", "&gt;");
  2324. text2.replace("<", "&lt;");
  2325. text = "<a name=\"";
  2326. text += QString::number(inhistory_current_id);
  2327. text += "\">";
  2328. text += text2;
  2329. text += "</a>";
  2330. inhistory.insert(inhistory.begin(), text2);
  2331. inhistory_type.insert(inhistory_type.begin(), QALCULATE_HISTORY_EXPRESSION);
  2332. inhistory_id.insert(inhistory_id.begin(), inhistory_current_id);
  2333. inhistory_index++;
  2334. inhistory_current_id++;
  2335. }
  2336. int l = text.length();
  2337. text += " <br><hr>";
  2338. text += historyBrowser->text();
  2339. history_index = l + 1;
  2340. historyBrowser->setText(text);
  2341. } else if(initial_result_index == 0) {
  2342. b_busy = false;
  2343. error_timer->start(100);
  2344. return;
  2345. } else {
  2346. inhistory_index = initial_inhistory_index;
  2347. if(!transformation.isEmpty()) {
  2348. transformation.replace("&", "&amp;");
  2349. transformation.replace(">", "&gt;");
  2350. transformation.replace("<", "&lt;");
  2351. inhistory.insert(inhistory.begin(), transformation);
  2352. inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_TRANSFORMATION);
  2353. inhistory_id.insert(inhistory_id.begin() + inhistory_index, inhistory_current_id);
  2354. inhistory_current_id++;
  2355. inhistory_index++;
  2356. transformation.insert(0, "<i>");
  2357. transformation += ": </i><br>";
  2358. QString text = historyBrowser->text();
  2359. text.insert(initial_result_index, transformation);
  2360. historyBrowser->setText(text);
  2361. initial_result_index += transformation.length() - 4;
  2362. }
  2363. history_index = initial_result_index;
  2364. }
  2365. result_history_text = "?";
  2366. }
  2367. if(update_parse) {
  2368. parsed_text = i18n("aborted");
  2369. }
  2370. if(stack_index == 0) {
  2371. resultLabel->setRightMargin(10);
  2372. resultLabel->setText("<font size=6> </font>");
  2373. result_parts.clear();
  2374. result_text = i18n("result processing was aborted");
  2375. }
  2376. *printops.is_approximate = false;
  2377. printops.prefix = prefix;
  2378. CALCULATOR->saveState();
  2379. bool parsed_approx = false;
  2380. bool do_wrap = true;
  2381. KQalculate *win = this;
  2382. fwrite(&win, sizeof(void*), 1, view_pipe_w);
  2383. if(stack_index == 0) {
  2384. fwrite(&mstruct, sizeof(void*), 1, view_pipe_w);
  2385. matrix_mstruct->clear();
  2386. fwrite(&matrix_mstruct, sizeof(void*), 1, view_pipe_w);
  2387. } else {
  2388. MathStructure *mreg = CALCULATOR->getRPNRegister(stack_index + 1);
  2389. fwrite(&mreg, sizeof(void*), 1, view_pipe_w);
  2390. void *x = NULL;
  2391. fwrite(&x, sizeof(void*), 1, view_pipe_w);
  2392. }
  2393. bool *b = &do_wrap;
  2394. fwrite(&b, sizeof(bool*), 1, view_pipe_w);
  2395. if(update_parse) {
  2396. fwrite(&parsed_mstruct, sizeof(void*), 1, view_pipe_w);
  2397. bool *parsed_approx_p = &parsed_approx;
  2398. fwrite(&parsed_approx_p, sizeof(void*), 1, view_pipe_w);
  2399. fwrite(&parsed_tostruct, sizeof(void*), 1, view_pipe_w);
  2400. } else {
  2401. void *x = NULL;
  2402. fwrite(&x, sizeof(void*), 1, view_pipe_w);
  2403. }
  2404. fflush(view_pipe_w);
  2405. struct timespec rtime;
  2406. rtime.tv_sec = 0;
  2407. rtime.tv_nsec = 20000000;
  2408. int i = 0;
  2409. while(b_busy && i < 50) {
  2410. nanosleep(&rtime, NULL);
  2411. i++;
  2412. }
  2413. i = 0;
  2414. KProgressDialog *dialog = NULL;
  2415. if(b_busy) {
  2416. dialog = new KProgressDialog(this, "display_progress_dialog", i18n("Processing..."), i18n("Processing..."), true);
  2417. dialog->progressBar()->setPercentageVisible(false);
  2418. dialog->progressBar()->setTotalSteps(0);
  2419. dialog->showCancelButton(true);
  2420. dialog->setButtonText(i18n("Abort"));
  2421. dialog->show();
  2422. }
  2423. if(dialog && dialog->wasCancelled()) on_abort_display();
  2424. rtime.tv_nsec = 100000000;
  2425. while(b_busy) {
  2426. dialog->progressBar()->advance(1);
  2427. qApp->processEvents();
  2428. nanosleep(&rtime, NULL);
  2429. if(dialog->wasCancelled()) on_abort_display();
  2430. }
  2431. b_busy = true;
  2432. if(dialog) {
  2433. dialog->hide();
  2434. delete dialog;
  2435. }
  2436. if(stack_index == 0) {
  2437. if(do_wrap) {
  2438. resultLabel->setVScrollBarMode(QScrollView::Auto);
  2439. resultLabel->setRightMargin(10);
  2440. resultLabel->setWordWrap(QTextEdit::NoWrap);
  2441. } else {
  2442. resultLabel->setVScrollBarMode(QScrollView::AlwaysOff);
  2443. resultLabel->setWordWrap(QTextEdit::NoWrap);
  2444. resultLabel->setRightMargin(0);
  2445. QString str = result_text;
  2446. str.replace("width=1 ", "");
  2447. QSimpleRichText testrt(str, resultLabel->font());
  2448. testrt.setWidth(resultLabel->visibleWidth() * 4);
  2449. if(testrt.widthUsed() > resultLabel->visibleWidth()) {
  2450. result_text.replace("<font size=5", "<font size=4");
  2451. result_text.replace("<font size=6", "<font size=5");
  2452. reduceDivLineSize(resultLabel);
  2453. }
  2454. }
  2455. resultLabel->setText(result_text);
  2456. }
  2457. if(register_moved) {
  2458. update_parse = true;
  2459. parsed_text = result_history_text;
  2460. }
  2461. if(update_history) {
  2462. if(result_history_text.length() > 500000) {
  2463. result_history_text = "(...)";
  2464. }
  2465. if(parsed_text.length() > 500000) {
  2466. parsed_text = "(...)";
  2467. }
  2468. QString new_text;
  2469. if(update_parse) {
  2470. QString str = "&nbsp;&nbsp;";
  2471. if(!parsed_approx) {
  2472. str += "=";
  2473. inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_PARSE);
  2474. } else {
  2475. if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) historyBrowser)) {
  2476. str += SIGN_ALMOST_EQUAL;
  2477. } else {
  2478. str += i18n("approx.");
  2479. }
  2480. inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_PARSE_APPROXIMATE);
  2481. }
  2482. str += " ";
  2483. QString str2 = parsed_text;
  2484. str2.replace("&", "&amp;");
  2485. str2.replace(">", "&gt;");
  2486. str2.replace("<", "&lt;");
  2487. inhistory.insert(inhistory.begin() + inhistory_index, str2);
  2488. inhistory_id.insert(inhistory_id.begin() + inhistory_index, inhistory_current_id);
  2489. inhistory_index++;
  2490. str += str2;
  2491. new_text += "<font color=\"gray40\"><i>";
  2492. new_text += "<a name=\"";
  2493. new_text += QString::number(inhistory_current_id);
  2494. new_text += "\">";
  2495. new_text += str;
  2496. new_text += "</a>";
  2497. new_text += "</i></font>";
  2498. new_text += "<br>";
  2499. inhistory_current_id++;
  2500. }
  2501. if(stack_index == 0) {
  2502. display_errors(&new_text, &inhistory_index);
  2503. new_text += "<a name=\"";
  2504. new_text += QString::number(inhistory_current_id);
  2505. new_text += "\">";
  2506. if(!(*printops.is_approximate) && !mstruct->isApproximate() && (update_parse || !prev_result_approx)) {
  2507. inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_RESULT);
  2508. new_text += "=";
  2509. } else {
  2510. inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_RESULT_APPROXIMATE);
  2511. if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) historyBrowser)) {
  2512. new_text += SIGN_ALMOST_EQUAL;
  2513. } else {
  2514. QString str_approx = "= ";
  2515. str_approx += i18n("approx.");
  2516. new_text += str_approx;
  2517. }
  2518. }
  2519. new_text += " ";
  2520. new_text += "</a>";
  2521. } else {
  2522. display_errors();
  2523. }
  2524. if(rpn_mode && !register_moved) {
  2525. RPNRegisterChanged(result_history_text, stack_index);
  2526. }
  2527. if(stack_index == 0) {
  2528. QString str2 = result_history_text;
  2529. str2.replace("&", "&amp;");
  2530. str2.replace(">", "&gt;");
  2531. str2.replace("<", "&lt;");
  2532. new_text += "<b>";
  2533. new_text += "<a name=\"";
  2534. new_text += QString::number(inhistory_current_id);
  2535. new_text += "\">";
  2536. new_text += str2;
  2537. new_text += " </a>";
  2538. new_text += "</b>";
  2539. inhistory.insert(inhistory.begin() + inhistory_index, str2);
  2540. inhistory_id.insert(inhistory_id.begin() + inhistory_index, inhistory_current_id);
  2541. inhistory_current_id++;
  2542. QString text = historyBrowser->text();
  2543. initial_result_index = history_index + new_text.length() + 4;
  2544. initial_inhistory_index = inhistory_index + 1;
  2545. if(!update_parse && transformation.isEmpty()) {
  2546. new_text += "<br>";
  2547. }
  2548. text.insert(history_index, new_text);
  2549. historyBrowser->setText(text);
  2550. prev_result_approx = *printops.is_approximate;
  2551. }
  2552. }
  2553. printops.prefix = NULL;
  2554. b_busy = false;
  2555. display_errors();
  2556. if(!register_moved && stack_index == 0 && mstruct->isMatrix() && matrix_mstruct->isMatrix()) {
  2557. qApp->processEvents();
  2558. expressionEdit->setFocus();
  2559. if(update_history && update_parse && force) expressionEdit->selectAll();
  2560. insertMatrixVector(matrix_mstruct, false, true, true);
  2561. }
  2562. error_timer->start(100);
  2563. }
  2564. void on_abort_command() {
  2565. pthread_cancel(command_thread);
  2566. CALCULATOR->restoreState();
  2567. CALCULATOR->clearBuffers();
  2568. b_busy = false;
  2569. command_thread_started = false;
  2570. }
  2571. void *command_proc(void *pipe) {
  2572. pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
  2573. pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
  2574. FILE *command_pipe = (FILE*) pipe;
  2575. while(true) {
  2576. void *x = NULL;
  2577. int command_type;
  2578. fread(&command_type, sizeof(int), 1, command_pipe);
  2579. fread(&x, sizeof(void*), 1, command_pipe);
  2580. switch(command_type) {
  2581. case COMMAND_FACTORIZE: {
  2582. if(!((MathStructure*) x)->integerFactorize()) {
  2583. ((MathStructure*) x)->factorize(evalops);
  2584. }
  2585. break;
  2586. }
  2587. case COMMAND_SIMPLIFY: {
  2588. ((MathStructure*) x)->simplify(evalops);
  2589. break;
  2590. }
  2591. }
  2592. b_busy = false;
  2593. }
  2594. return NULL;
  2595. }
  2596. int execute_command_command_type;
  2597. void KQalculate::executeCommand(int command_type) {
  2598. execute_command_command_type = command_type;
  2599. if(expression_has_changed && !rpn_mode) {
  2600. execute_expression();
  2601. }
  2602. QTimer::singleShot(0, this, SLOT(executeCommand2()));
  2603. }
  2604. void KQalculate::executeCommand2() {
  2605. int command_type = execute_command_command_type;
  2606. error_timer->stop();
  2607. b_busy = true;
  2608. bool command_aborted = false;
  2609. CALCULATOR->saveState();
  2610. if(!command_thread_started) {
  2611. pthread_create(&command_thread, &command_thread_attr, command_proc, command_pipe_r);
  2612. command_thread_started = true;
  2613. }
  2614. fwrite(&command_type, sizeof(int), 1, command_pipe_w);
  2615. MathStructure *mfactor = new MathStructure(*mstruct);
  2616. fwrite(&mfactor, sizeof(void*), 1, command_pipe_w);
  2617. fflush(command_pipe_w);
  2618. struct timespec rtime;
  2619. rtime.tv_sec = 0;
  2620. rtime.tv_nsec = 20000000;
  2621. int i = 0;
  2622. while(b_busy && i < 50) {
  2623. nanosleep(&rtime, NULL);
  2624. i++;
  2625. }
  2626. i = 0;
  2627. KProgressDialog *dialog = NULL;
  2628. if(b_busy) {
  2629. QString progress_str;
  2630. switch(command_type) {
  2631. case COMMAND_FACTORIZE: {
  2632. progress_str = i18n("Factorizing...");
  2633. break;
  2634. }
  2635. case COMMAND_SIMPLIFY: {
  2636. progress_str = i18n("Simplifying...");
  2637. break;
  2638. }
  2639. }
  2640. dialog = new KProgressDialog(this, "display_progress_dialog", progress_str, progress_str, true);
  2641. dialog->progressBar()->setPercentageVisible(false);
  2642. dialog->progressBar()->setTotalSteps(0);
  2643. dialog->showCancelButton(true);
  2644. dialog->setButtonText(i18n("Abort"));
  2645. dialog->show();
  2646. }
  2647. if(dialog && dialog->wasCancelled()) {
  2648. on_abort_command();
  2649. command_aborted = true;
  2650. }
  2651. rtime.tv_nsec = 100000000;
  2652. while(b_busy) {
  2653. dialog->progressBar()->advance(1);
  2654. qApp->processEvents();
  2655. nanosleep(&rtime, NULL);
  2656. if(dialog->wasCancelled()) {
  2657. on_abort_command();
  2658. command_aborted = true;
  2659. }
  2660. }
  2661. b_busy = true;
  2662. if(dialog) {
  2663. dialog->hide();
  2664. delete dialog;
  2665. }
  2666. b_busy = false;
  2667. if(!command_aborted) {
  2668. mstruct->unref();
  2669. mstruct = mfactor;
  2670. switch(command_type) {
  2671. case COMMAND_FACTORIZE: {
  2672. printops.allow_factorization = true;
  2673. break;
  2674. }
  2675. case COMMAND_SIMPLIFY: {
  2676. printops.allow_factorization = false;
  2677. break;
  2678. }
  2679. }
  2680. set_result_prefix = NULL;
  2681. set_result_update_history = true;
  2682. set_result_update_parse = false;
  2683. set_result_force = true;
  2684. set_result_transformation = "";
  2685. set_result_stack_index = 0;
  2686. set_result_register_moved = false;
  2687. setResult2();
  2688. expressionEdit->setFocus();
  2689. }
  2690. error_timer->start(100);
  2691. }
  2692. void KQalculate::result_display_updated() {
  2693. setResult(NULL, false, false, false);
  2694. update_status_text();
  2695. expressionEdit->setFocus();
  2696. }
  2697. void KQalculate::result_format_updated() {
  2698. setResult(NULL, true, false, false);
  2699. update_status_text();
  2700. expressionEdit->setFocus();
  2701. }
  2702. void KQalculate::result_action_executed() {
  2703. //display_errors();
  2704. printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
  2705. setResult(NULL, true, false, true);
  2706. expressionEdit->setFocus();
  2707. }
  2708. void KQalculate::result_prefix_changed(Prefix *prefix) {
  2709. setResult(prefix, true, false, true);
  2710. expressionEdit->setFocus();
  2711. }
  2712. void KQalculate::expression_calculation_updated() {
  2713. expression_has_changed2 = true;
  2714. displayParseStatus();
  2715. if(!rpn_mode) execute_expression(false);
  2716. update_status_text();
  2717. expressionEdit->setFocus();
  2718. }
  2719. void KQalculate::expression_format_updated(bool recalculate) {
  2720. if(rpn_mode) recalculate = false;
  2721. expression_has_changed2 = true;
  2722. displayParseStatus();
  2723. if(!expression_has_changed && !recalculate && !rpn_mode) {
  2724. clearresult();
  2725. }
  2726. if(recalculate) {
  2727. execute_expression(false);
  2728. }
  2729. update_status_text();
  2730. expressionEdit->setFocus();
  2731. }
  2732. /*
  2733. calculate entered expression and display result
  2734. */
  2735. size_t execute_expression_stack_index;
  2736. bool execute_expression_do_stack;
  2737. bool execute_expression_force;
  2738. bool execute_expression_do_mathoperation;
  2739. MathOperation execute_expression_op;
  2740. MathFunction *execute_expression_f;
  2741. void KQalculate::execute_expression(bool force) {
  2742. execute_expression_force = force;
  2743. execute_expression_do_stack = false;
  2744. execute_expression_do_mathoperation = false;
  2745. QTimer::singleShot(0, this, SLOT(execute_expression2()));
  2746. }
  2747. void KQalculate::execute_expression2() {
  2748. bool force = execute_expression_force;
  2749. bool do_stack = execute_expression_do_stack;
  2750. size_t stack_index = execute_expression_stack_index;
  2751. bool do_mathoperation = execute_expression_do_mathoperation;
  2752. MathOperation op = execute_expression_op;
  2753. MathFunction *f = execute_expression_f;
  2754. QString str;
  2755. if(do_stack) {
  2756. str = getRPNRegister(stack_index)->text(1).stripWhiteSpace();
  2757. error_timer->stop();
  2758. } else {
  2759. str = expressionEdit->text().stripWhiteSpace();
  2760. if(!force && (expression_has_changed || str.isEmpty())) return;
  2761. error_timer->stop();
  2762. expression_has_changed = false;
  2763. if(!do_mathoperation && !str.isEmpty()) expressionEdit->addToHistory(expressionEdit->text());
  2764. }
  2765. size_t stack_size = 0;
  2766. b_busy = true;
  2767. if(!do_stack || stack_index == 0) {
  2768. parsed_text = "";
  2769. }
  2770. if(do_stack) {
  2771. stack_size = CALCULATOR->RPNStackSize();
  2772. CALCULATOR->setRPNRegister(stack_index + 1, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), 0, evalops, parsed_mstruct, parsed_tostruct, !printops.negative_exponents);
  2773. } else if(rpn_mode) {
  2774. stack_size = CALCULATOR->RPNStackSize();
  2775. if(do_mathoperation) {
  2776. if(f) CALCULATOR->calculateRPN(f, 0, evalops, parsed_mstruct);
  2777. else CALCULATOR->calculateRPN(op, 0, evalops, parsed_mstruct);
  2778. } else {
  2779. string str2 = CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options);
  2780. CALCULATOR->parseSigns(str2);
  2781. if(str2.length() == 1) {
  2782. do_mathoperation = true;
  2783. switch(str2[0]) {
  2784. case '^': {CALCULATOR->calculateRPN(OPERATION_RAISE, 0, evalops, parsed_mstruct); break;}
  2785. case '+': {CALCULATOR->calculateRPN(OPERATION_ADD, 0, evalops, parsed_mstruct); break;}
  2786. case '-': {CALCULATOR->calculateRPN(OPERATION_SUBTRACT, 0, evalops, parsed_mstruct); break;}
  2787. case '*': {CALCULATOR->calculateRPN(OPERATION_MULTIPLY, 0, evalops, parsed_mstruct); break;}
  2788. case '/': {CALCULATOR->calculateRPN(OPERATION_DIVIDE, 0, evalops, parsed_mstruct); break;}
  2789. case '&': {CALCULATOR->calculateRPN(OPERATION_BITWISE_AND, 0, evalops, parsed_mstruct); break;}
  2790. case '|': {CALCULATOR->calculateRPN(OPERATION_BITWISE_OR, 0, evalops, parsed_mstruct); break;}
  2791. case '~': {CALCULATOR->calculateRPNBitwiseNot(0, evalops, parsed_mstruct); break;}
  2792. case '!': {CALCULATOR->calculateRPN(CALCULATOR->f_factorial, 0, evalops, parsed_mstruct); break;}
  2793. case '>': {CALCULATOR->calculateRPN(OPERATION_GREATER, 0, evalops, parsed_mstruct); break;}
  2794. case '<': {CALCULATOR->calculateRPN(OPERATION_LESS, 0, evalops, parsed_mstruct); break;}
  2795. case '=': {CALCULATOR->calculateRPN(OPERATION_EQUALS, 0, evalops, parsed_mstruct); break;}
  2796. default: {do_mathoperation = false;}
  2797. }
  2798. } else if(str2.length() == 2) {
  2799. if(str2 == "**") {
  2800. CALCULATOR->calculateRPN(OPERATION_RAISE, 0, evalops, parsed_mstruct);
  2801. do_mathoperation = true;
  2802. } else if(str2 == "!!") {
  2803. CALCULATOR->calculateRPN(CALCULATOR->f_factorial2, 0, evalops, parsed_mstruct);
  2804. do_mathoperation = true;
  2805. } else if(str2 == "!=" || str == "=!" || str == "<>") {
  2806. CALCULATOR->calculateRPN(OPERATION_NOT_EQUALS, 0, evalops, parsed_mstruct);
  2807. do_mathoperation = true;
  2808. } else if(str2 == "<=" || str == "=<") {
  2809. CALCULATOR->calculateRPN(OPERATION_EQUALS_LESS, 0, evalops, parsed_mstruct);
  2810. do_mathoperation = true;
  2811. } else if(str2 == ">=" || str == "=>") {
  2812. CALCULATOR->calculateRPN(OPERATION_EQUALS_GREATER, 0, evalops, parsed_mstruct);
  2813. do_mathoperation = true;
  2814. } else if(str2 == "==") {
  2815. CALCULATOR->calculateRPN(OPERATION_EQUALS, 0, evalops, parsed_mstruct);
  2816. do_mathoperation = true;
  2817. }
  2818. }
  2819. if(!do_mathoperation) {
  2820. bool had_nonnum = false, test_function = true;
  2821. int in_par = 0;
  2822. for(size_t i = 0; i < str2.length(); i++) {
  2823. if(is_in(NUMBERS, str2[i])) {
  2824. if(!had_nonnum || in_par) {
  2825. test_function = false;
  2826. break;
  2827. }
  2828. } else if(str2[i] == '(') {
  2829. if(in_par || !had_nonnum) {
  2830. test_function = false;
  2831. break;
  2832. }
  2833. in_par = i;
  2834. } else if(str2[i] == ')') {
  2835. if(i != str2.length() - 1) {
  2836. test_function = false;
  2837. break;
  2838. }
  2839. } else if(str2[i] == ' ') {
  2840. if(!in_par) {
  2841. test_function = false;
  2842. break;
  2843. }
  2844. } else if(is_in(NOT_IN_NAMES, str2[i])) {
  2845. test_function = false;
  2846. break;
  2847. } else {
  2848. if(in_par) {
  2849. test_function = false;
  2850. break;
  2851. }
  2852. had_nonnum = true;
  2853. }
  2854. }
  2855. f = NULL;
  2856. if(test_function) {
  2857. if(in_par) f = CALCULATOR->getActiveFunction(str2.substr(0, in_par));
  2858. else f = CALCULATOR->getActiveFunction(str2);
  2859. }
  2860. if(f && f->minargs() > 1) {
  2861. KMessageBox::error(this, "Can only apply functions wich requires one argument on RPN stack.");
  2862. f = NULL;
  2863. return;
  2864. }
  2865. if(f && f->minargs() > 0) {
  2866. do_mathoperation = true;
  2867. CALCULATOR->calculateRPN(f, 0, evalops, parsed_mstruct);
  2868. } else {
  2869. CALCULATOR->RPNStackEnter(str2, 0, evalops, parsed_mstruct, parsed_tostruct, !printops.negative_exponents);
  2870. }
  2871. }
  2872. }
  2873. } else {
  2874. CALCULATOR->calculate(mstruct, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), 0, evalops, parsed_mstruct, parsed_tostruct, !printops.negative_exponents);
  2875. }
  2876. struct timespec rtime;
  2877. rtime.tv_sec = 0;
  2878. rtime.tv_nsec = 20000000;
  2879. int i = 0;
  2880. while(CALCULATOR->busy() && i < 50) {
  2881. nanosleep(&rtime, NULL);
  2882. i++;
  2883. }
  2884. i = 0;
  2885. KProgressDialog *dialog = NULL;
  2886. if(CALCULATOR->busy()) {
  2887. dialog = new KProgressDialog(this, "calculation_progress_dialog", i18n("Calculating..."), i18n("Calculating..."), true);
  2888. dialog->progressBar()->setPercentageVisible(false);
  2889. dialog->progressBar()->setTotalSteps(0);
  2890. dialog->showCancelButton(true);
  2891. dialog->setButtonText(i18n("Abort"));
  2892. dialog->show();
  2893. }
  2894. if(dialog && dialog->wasCancelled()) CALCULATOR->abort();
  2895. rtime.tv_nsec = 100000000;
  2896. while(CALCULATOR->busy()) {
  2897. dialog->progressBar()->advance(1);
  2898. qApp->processEvents();
  2899. nanosleep(&rtime, NULL);
  2900. if(dialog->wasCancelled()) CALCULATOR->abort();
  2901. }
  2902. if(dialog) {
  2903. dialog->hide();
  2904. delete dialog;
  2905. expressionEdit->setFocus();
  2906. }
  2907. b_busy = false;
  2908. if(rpn_mode && (!do_stack || stack_index == 0)) {
  2909. mstruct->unref();
  2910. mstruct = CALCULATOR->getRPNRegister(1);
  2911. if(!mstruct) mstruct = new MathStructure();
  2912. else mstruct->ref();
  2913. }
  2914. //update "ans" variables
  2915. if(!do_stack || stack_index == 0) {
  2916. vans[4]->set(vans[3]->get());
  2917. vans_id_start[4] = vans_id_start[3];
  2918. vans_id_end[4] = vans_id_end[3];
  2919. vans[3]->set(vans[2]->get());
  2920. vans_id_start[3] = vans_id_start[2];
  2921. vans_id_end[3] = vans_id_end[2];
  2922. vans[2]->set(vans[1]->get());
  2923. vans_id_start[2] = vans_id_start[1];
  2924. vans_id_end[2] = vans_id_end[1];
  2925. vans[1]->set(vans[0]->get());
  2926. vans_id_start[1] = vans_id_start[0];
  2927. vans_id_end[1] = inhistory_current_id - 1;
  2928. vans[0]->set(*mstruct);
  2929. vans_id_start[0] = inhistory_current_id;
  2930. vans_id_end[0] = -1;
  2931. }
  2932. if(do_stack && stack_index > 0) {
  2933. } else if(rpn_mode && do_mathoperation) {
  2934. result_history_text = i18n("RPN Operation");
  2935. } else {
  2936. result_history_text = str;
  2937. }
  2938. printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
  2939. set_result_prefix = NULL;
  2940. set_result_update_history = true;
  2941. set_result_update_parse = (!do_stack || stack_index == 0);
  2942. set_result_force = true;
  2943. set_result_transformation = "";
  2944. set_result_register_moved = false;
  2945. if(!do_stack) set_result_stack_index = 0;
  2946. else set_result_stack_index = stack_index;
  2947. if(rpn_mode && (!do_stack || stack_index == 0)) {
  2948. expressionEdit->clear();
  2949. if(CALCULATOR->RPNStackSize() < stack_size) {
  2950. RPNRegisterRemoved(1);
  2951. } else if(CALCULATOR->RPNStackSize() > stack_size) {
  2952. RPNRegisterAdded("");
  2953. }
  2954. }
  2955. setResult2();
  2956. if(!do_stack || stack_index == 0) {
  2957. expressionEdit->setFocus();
  2958. expressionEdit->selectAll();
  2959. }
  2960. error_timer->start(100);
  2961. }
  2962. void KQalculate::display_errors(QString *new_text, int *inhistory_index) {
  2963. if(!CALCULATOR->message()) return;
  2964. error_timer->stop();
  2965. bool error = false;
  2966. MessageType mtype;
  2967. QStringList strlst;
  2968. QString error_str = "";
  2969. while(true) {
  2970. mtype = CALCULATOR->message()->type();
  2971. if(mtype == MESSAGE_ERROR || mtype == MESSAGE_WARNING) {
  2972. QString text = CALCULATOR->message()->message().c_str();
  2973. text.replace("&", "&amp;");
  2974. text.replace(">", "&gt;");
  2975. text.replace("<", "&lt;");
  2976. if(inhistory_index) {
  2977. inhistory.insert(inhistory.begin() + *inhistory_index, text);
  2978. inhistory_id.insert(inhistory_id.begin() + *inhistory_index, inhistory_current_id);
  2979. inhistory_current_id++;
  2980. if(mtype == MESSAGE_ERROR) inhistory_type.insert(inhistory_type.begin() + *inhistory_index, QALCULATE_HISTORY_ERROR);
  2981. else inhistory_type.insert(inhistory_type.begin() + *inhistory_index, QALCULATE_HISTORY_WARNING);
  2982. *inhistory_index += 1;
  2983. }
  2984. strlst.push_back(CALCULATOR->message()->message().c_str());
  2985. if(mtype == MESSAGE_ERROR) error = true;
  2986. if(mtype == MESSAGE_ERROR) error_str += "<font color=\"red\">";
  2987. else error_str += "<font color=\"blue\">";
  2988. error_str += "- ";
  2989. error_str += text;
  2990. error_str += "</font>";
  2991. error_str += "<br>";
  2992. } else {
  2993. KMessageBox::information(this, CALCULATOR->message()->message().c_str());
  2994. }
  2995. if(!CALCULATOR->nextMessage()) break;
  2996. }
  2997. if(!error_str.isEmpty() && new_text) {
  2998. new_text->append(error_str);
  2999. }
  3000. if(strlst.size() > 1) {
  3001. if(error) KMessageBox::error(this, strlst.join("\n"), i18n("Errors"));
  3002. else KMessageBox::error(this, strlst.join("\n"), i18n("Warnings"));
  3003. } else if(strlst.size() == 1) {
  3004. if(error) KMessageBox::error(this, strlst[0], i18n("Error"));
  3005. else KMessageBox::error(this, strlst[0], i18n("Warning"));
  3006. }
  3007. error_timer->start(100);
  3008. }
  3009. void save_defs() {
  3010. if(!CALCULATOR->saveDefinitions()) {
  3011. KMessageBox::error(0, i18n("Couldn't write definitions"));
  3012. }
  3013. }
  3014. void KQalculate::create_vmenu() {
  3015. QPopupMenu *sub, *sub3;
  3016. menu_variables->clear();
  3017. sub = menu_variables;
  3018. Variable *v;
  3019. tree_struct *titem, *titem2;
  3020. variable_cats.rit = variable_cats.items.rbegin();
  3021. if(variable_cats.rit != variable_cats.items.rend()) {
  3022. titem = &*variable_cats.rit;
  3023. ++variable_cats.rit;
  3024. titem->rit = titem->items.rbegin();
  3025. } else {
  3026. titem = NULL;
  3027. }
  3028. menu_variables_ids.clear();
  3029. stack<QPopupMenu*> menus;
  3030. menus.push(sub);
  3031. sub3 = sub;
  3032. while(titem) {
  3033. sub = new QPopupMenu();
  3034. QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onVariableMenuItemActivated(int)));
  3035. if(titem->item.find('&') != string::npos) {
  3036. QString str2 = titem->item.c_str();
  3037. str2.replace("&", "&&");
  3038. sub3->insertItem(str2, sub, -1, 0);
  3039. } else {
  3040. sub3->insertItem(titem->item.c_str(), sub, -1, 0);
  3041. }
  3042. menus.push(sub);
  3043. sub3 = sub;
  3044. for(size_t i = 0; i < titem->objects.size(); i++) {
  3045. v = (Variable*) titem->objects[i];
  3046. if(v->isActive() && !v->isHidden()) {
  3047. if(v->title(true).find('&') != string::npos) {
  3048. QString str2 = v->title(true).c_str();
  3049. str2.replace("&", "&&");
  3050. menu_variables_ids[sub->insertItem(str2)] = v;
  3051. } else {
  3052. menu_variables_ids[sub->insertItem(v->title(true).c_str())] = v;
  3053. }
  3054. }
  3055. }
  3056. while(titem && titem->rit == titem->items.rend()) {
  3057. titem = titem->parent;
  3058. menus.pop();
  3059. if(menus.size() > 0) sub3 = menus.top();
  3060. }
  3061. if(titem) {
  3062. titem2 = &*titem->rit;
  3063. ++titem->rit;
  3064. titem = titem2;
  3065. titem->rit = titem->items.rbegin();
  3066. }
  3067. }
  3068. for(size_t i = 0; i < variable_cats.objects.size(); i++) {
  3069. v = (Variable*) variable_cats.objects[i];
  3070. if(v->isActive() && !v->isHidden()) {
  3071. menu_variables_ids[menu_variables->insertItem(v->title(true).c_str())] = v;
  3072. }
  3073. }
  3074. }
  3075. void KQalculate::recreate_recent_variables() {
  3076. recent_variable_ids.clear();
  3077. bool b = false;
  3078. for(size_t i = 0; i < recent_variables.size(); i++) {
  3079. if(!CALCULATOR->stillHasVariable(recent_variables[i])) {
  3080. recent_variables.erase(recent_variables.begin() + i);
  3081. i--;
  3082. } else {
  3083. if(!b) {
  3084. menu_variables->insertSeparator(0);
  3085. b = true;
  3086. }
  3087. int id = menu_variables->insertItem(recent_variables[i]->title(true).c_str(), -1, 0);
  3088. recent_variable_ids.push_back(id);
  3089. menu_variables_ids[id] = recent_variables[i];
  3090. }
  3091. }
  3092. }
  3093. void KQalculate::update_vmenu() {
  3094. generate_variables_tree_struct();
  3095. create_vmenu();
  3096. recreate_recent_variables();
  3097. if(variables_dialog) variables_dialog->updateVariableTree();
  3098. update_completion();
  3099. }
  3100. void KQalculate::create_fmenu() {
  3101. QPopupMenu *sub, *sub3;
  3102. menu_functions->clear();
  3103. sub = menu_functions;
  3104. MathFunction *f;
  3105. tree_struct *titem, *titem2;
  3106. function_cats.rit = function_cats.items.rbegin();
  3107. if(function_cats.rit != function_cats.items.rend()) {
  3108. titem = &*function_cats.rit;
  3109. ++function_cats.rit;
  3110. titem->rit = titem->items.rbegin();
  3111. } else {
  3112. titem = NULL;
  3113. }
  3114. menu_functions_ids.clear();
  3115. stack<QPopupMenu*> menus;
  3116. menus.push(sub);
  3117. sub3 = sub;
  3118. while(titem) {
  3119. sub = new QPopupMenu();
  3120. QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onFunctionMenuItemActivated(int)));
  3121. if(titem->item.find('&') != string::npos) {
  3122. QString str2 = titem->item.c_str();
  3123. str2.replace("&", "&&");
  3124. sub3->insertItem(str2, sub, -1, 0);
  3125. } else {
  3126. sub3->insertItem(titem->item.c_str(), sub, -1, 0);
  3127. }
  3128. menus.push(sub);
  3129. sub3 = sub;
  3130. for(size_t i = 0; i < titem->objects.size(); i++) {
  3131. f = (MathFunction*) titem->objects[i];
  3132. if(f->isActive() && !f->isHidden()) {
  3133. if(f->title(true).find('&') != string::npos) {
  3134. QString str2 = f->title(true).c_str();
  3135. str2.replace("&", "&&");
  3136. menu_functions_ids[sub->insertItem(str2)] = f;
  3137. } else {
  3138. menu_functions_ids[sub->insertItem(f->title(true).c_str())] = f;
  3139. }
  3140. }
  3141. }
  3142. while(titem && titem->rit == titem->items.rend()) {
  3143. titem = titem->parent;
  3144. menus.pop();
  3145. if(menus.size() > 0) sub3 = menus.top();
  3146. }
  3147. if(titem) {
  3148. titem2 = &*titem->rit;
  3149. ++titem->rit;
  3150. titem = titem2;
  3151. titem->rit = titem->items.rbegin();
  3152. }
  3153. }
  3154. for(size_t i = 0; i < function_cats.objects.size(); i++) {
  3155. f = (MathFunction*) function_cats.objects[i];
  3156. if(f->isActive() && !f->isHidden()) {
  3157. menu_functions_ids[menu_functions->insertItem(f->title(true).c_str())] = f;
  3158. }
  3159. }
  3160. }
  3161. void KQalculate::recreate_recent_functions() {
  3162. recent_function_ids.clear();
  3163. bool b = false;
  3164. for(size_t i = 0; i < recent_functions.size(); i++) {
  3165. if(!CALCULATOR->stillHasFunction(recent_functions[i])) {
  3166. recent_functions.erase(recent_functions.begin() + i);
  3167. i--;
  3168. } else {
  3169. if(!b) {
  3170. menu_functions->insertSeparator(0);
  3171. b = true;
  3172. }
  3173. int id = menu_functions->insertItem(recent_functions[i]->title(true).c_str(), -1, 0);
  3174. recent_function_ids.push_back(id);
  3175. menu_functions_ids[id] = recent_functions[i];
  3176. }
  3177. }
  3178. }
  3179. void KQalculate::update_fmenu() {
  3180. generate_functions_tree_struct();
  3181. create_fmenu();
  3182. recreate_recent_functions();
  3183. if(functions_dialog) functions_dialog->updateFunctionTree();
  3184. if(datasets_dialog) {
  3185. datasets_dialog->updateDataSetTree();
  3186. if(!datasets_dialog->dataSetsView->selectedItem()) datasets_dialog->dataSetSelected();
  3187. }
  3188. update_completion();
  3189. }
  3190. void KQalculate::create_umenu() {
  3191. QPopupMenu *sub, *sub3;
  3192. menu_units->clear();
  3193. sub = menu_units;
  3194. Unit *u;
  3195. tree_struct *titem, *titem2;
  3196. unit_cats.rit = unit_cats.items.rbegin();
  3197. if(unit_cats.rit != unit_cats.items.rend()) {
  3198. titem = &*unit_cats.rit;
  3199. ++unit_cats.rit;
  3200. titem->rit = titem->items.rbegin();
  3201. } else {
  3202. titem = NULL;
  3203. }
  3204. menu_units_ids.clear();
  3205. stack<QPopupMenu*> menus;
  3206. menus.push(sub);
  3207. sub3 = sub;
  3208. while(titem) {
  3209. sub = new QPopupMenu();
  3210. QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onUnitMenuItemActivated(int)));
  3211. if(titem->item.find('&') != string::npos) {
  3212. QString str2 = titem->item.c_str();
  3213. str2.replace("&", "&&");
  3214. sub3->insertItem(str2, sub, -1, 0);
  3215. } else {
  3216. sub3->insertItem(titem->item.c_str(), sub, -1, 0);
  3217. }
  3218. menus.push(sub);
  3219. sub3 = sub;
  3220. for(size_t i = 0; i < titem->objects.size(); i++) {
  3221. u = (Unit*) titem->objects[i];
  3222. if(u->isActive() && !u->isHidden()) {
  3223. if(u->title(true).find('&') != string::npos) {
  3224. QString str2 = u->title(true).c_str();
  3225. str2.replace("&", "&&");
  3226. menu_units_ids[sub->insertItem(str2)] = u;
  3227. } else {
  3228. menu_units_ids[sub->insertItem(u->title(true).c_str())] = u;
  3229. }
  3230. }
  3231. }
  3232. while(titem && titem->rit == titem->items.rend()) {
  3233. titem = titem->parent;
  3234. menus.pop();
  3235. if(menus.size() > 0) sub3 = menus.top();
  3236. }
  3237. if(titem) {
  3238. titem2 = &*titem->rit;
  3239. ++titem->rit;
  3240. titem = titem2;
  3241. titem->rit = titem->items.rbegin();
  3242. }
  3243. }
  3244. for(size_t i = 0; i < unit_cats.objects.size(); i++) {
  3245. u = (Unit*) unit_cats.objects[i];
  3246. if(u->isActive() && !u->isHidden()) {
  3247. menu_units_ids[menu_units->insertItem(u->title(true).c_str())] = u;
  3248. }
  3249. }
  3250. sub = new QPopupMenu();
  3251. QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onUnitsPrefixMenuItemActivated(int)));
  3252. menu_units->insertSeparator();
  3253. menu_units->insertItem(i18n("Prefixes"), sub);
  3254. int index = 0;
  3255. Prefix *p = CALCULATOR->getPrefix(index);
  3256. while(p) {
  3257. QString pstr;
  3258. switch(p->type()) {
  3259. case PREFIX_DECIMAL: {
  3260. QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str() << "\t(10e" << ((DecimalPrefix*) p)->exponent() << ")";
  3261. break;
  3262. }
  3263. case PREFIX_BINARY: {
  3264. QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str() << "\t(2e" << ((BinaryPrefix*) p)->exponent() << ")";
  3265. break;
  3266. }
  3267. case PREFIX_NUMBER: {
  3268. QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str();
  3269. break;
  3270. }
  3271. }
  3272. menu_units_prefixes_ids[sub->insertItem(pstr)] = p;
  3273. index++;
  3274. p = CALCULATOR->getPrefix(index);
  3275. }
  3276. }
  3277. void KQalculate::recreate_recent_units() {
  3278. recent_unit_ids.clear();
  3279. bool b = false;
  3280. for(size_t i = 0; i < recent_units.size(); i++) {
  3281. if(!CALCULATOR->stillHasUnit(recent_units[i])) {
  3282. recent_units.erase(recent_units.begin() + i);
  3283. i--;
  3284. } else {
  3285. if(!b) {
  3286. menu_units->insertSeparator(0);
  3287. b = true;
  3288. }
  3289. int id = menu_units->insertItem(recent_units[i]->title(true).c_str(), -1, 0);
  3290. recent_unit_ids.push_back(id);
  3291. menu_units_ids[id] = recent_units[i];
  3292. }
  3293. }
  3294. }
  3295. void KQalculate::update_umenus() {
  3296. generate_units_tree_struct();
  3297. create_umenu();
  3298. recreate_recent_units();
  3299. create_toumenu();
  3300. if(units_dialog) units_dialog->updateUnitTree();
  3301. if(convert_to_unit_expression_dialog) convert_to_unit_expression_dialog->updateUnitTree();
  3302. update_completion();
  3303. }
  3304. void KQalculate::create_toumenu() {
  3305. QPopupMenu *sub, *sub3;
  3306. menu_to_unit->clear();
  3307. sub = menu_to_unit;
  3308. Unit *u;
  3309. tree_struct *titem, *titem2;
  3310. unit_cats.rit = unit_cats.items.rbegin();
  3311. if(unit_cats.rit != unit_cats.items.rend()) {
  3312. titem = &*unit_cats.rit;
  3313. ++unit_cats.rit;
  3314. titem->rit = titem->items.rbegin();
  3315. } else {
  3316. titem = NULL;
  3317. }
  3318. menu_to_unit_ids.clear();
  3319. stack<QPopupMenu*> menus;
  3320. menus.push(sub);
  3321. sub3 = sub;
  3322. while(titem) {
  3323. sub = new QPopupMenu();
  3324. QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onConvertToUnitMenuItemActivated(int)));
  3325. if(titem->item.find('&') != string::npos) {
  3326. QString str2 = titem->item.c_str();
  3327. str2.replace("&", "&&");
  3328. sub3->insertItem(str2, sub, -1, 0);
  3329. } else {
  3330. sub3->insertItem(titem->item.c_str(), sub, -1, 0);
  3331. }
  3332. menus.push(sub);
  3333. sub3 = sub;
  3334. for(size_t i = 0; i < titem->objects.size(); i++) {
  3335. u = (Unit*) titem->objects[i];
  3336. if(u->isActive() && !u->isHidden()) {
  3337. if(u->title(true).find('&') != string::npos) {
  3338. QString str2 = u->title(true).c_str();
  3339. str2.replace("&", "&&");
  3340. menu_to_unit_ids[sub->insertItem(str2)] = u;
  3341. } else {
  3342. menu_to_unit_ids[sub->insertItem(u->title(true).c_str())] = u;
  3343. }
  3344. }
  3345. }
  3346. while(titem && titem->rit == titem->items.rend()) {
  3347. titem = titem->parent;
  3348. menus.pop();
  3349. if(menus.size() > 0) sub3 = menus.top();
  3350. }
  3351. if(titem) {
  3352. titem2 = &*titem->rit;
  3353. ++titem->rit;
  3354. titem = titem2;
  3355. titem->rit = titem->items.rbegin();
  3356. }
  3357. }
  3358. for(size_t i = 0; i < unit_cats.objects.size(); i++) {
  3359. u = (Unit*) unit_cats.objects[i];
  3360. if(u->isActive() && !u->isHidden()) {
  3361. menu_to_unit_ids[menu_to_unit->insertItem(u->title(true).c_str())] = u;
  3362. }
  3363. }
  3364. }
  3365. void KQalculate::create_setpmenu() {
  3366. menu_set_prefix->clear();
  3367. QObject::connect(menu_set_prefix, SIGNAL(activated(int)), this, SLOT(onSetPrefixMenuItemActivated(int)));
  3368. int index = 0;
  3369. menu_set_prefix_ids[menu_set_prefix->insertItem(i18n("No Prefix"))] = CALCULATOR->decimal_null_prefix;
  3370. Prefix *p = CALCULATOR->getPrefix(index);
  3371. while(p) {
  3372. QString pstr;
  3373. switch(p->type()) {
  3374. case PREFIX_DECIMAL: {
  3375. QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str() << "\t(10e" << ((DecimalPrefix*) p)->exponent() << ")";
  3376. break;
  3377. }
  3378. case PREFIX_BINARY: {
  3379. QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str() << "\t(2e" << ((BinaryPrefix*) p)->exponent() << ")";
  3380. break;
  3381. }
  3382. case PREFIX_NUMBER: {
  3383. QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str();
  3384. break;
  3385. }
  3386. }
  3387. menu_set_prefix_ids[menu_set_prefix->insertItem(pstr)] = p;
  3388. index++;
  3389. p = CALCULATOR->getPrefix(index);
  3390. }
  3391. }
  3392. void KQalculate::insert_text(QString name) {
  3393. expressionEdit->insert(name);
  3394. expressionEdit->setFocus();
  3395. }
  3396. /*
  3397. insert one-argument function when button clicked
  3398. */
  3399. void KQalculate::insertButtonFunction(QString text, bool append_space) {
  3400. if(expressionEdit->hasSelectedText()) {
  3401. //set selection as argument
  3402. text += "(";
  3403. text += expressionEdit->selectedText();
  3404. text += ")";
  3405. insert_text(text);
  3406. } else {
  3407. //one-argument functions do not need parenthesis
  3408. if(append_space) {
  3409. text += " ";
  3410. }
  3411. insert_text(text);
  3412. }
  3413. }
  3414. void KQalculate::insertButtonFunction(MathFunction *f) {
  3415. const ExpressionName *ename = &f->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit);
  3416. if(f->minargs() > 1) {
  3417. QString text = ename->name.c_str();
  3418. bool b = expressionEdit->hasSelectedText();
  3419. text += "(";
  3420. if(b) text += expressionEdit->selectedText();
  3421. for(int i = 1; i < f->minargs(); i++) {
  3422. text += CALCULATOR->getComma().c_str();
  3423. text += " ";
  3424. }
  3425. text += ")";
  3426. insert_text(text);
  3427. if(b) expressionEdit->cursorBackward(false, 1 + (f->minargs() - 2) * 2);
  3428. else expressionEdit->cursorBackward(false, 1 + (f->minargs() - 1) * 2);
  3429. } else {
  3430. if(rpn_mode && f->args() == 1) {
  3431. calculateRPN(f);
  3432. return;
  3433. }
  3434. insertButtonFunction(ename->name.c_str(), !text_length_is_one(ename->name));
  3435. }
  3436. }
  3437. void KQalculate::function_inserted(MathFunction *object) {
  3438. if(!object) {
  3439. return;
  3440. }
  3441. if(recent_function_ids.size() <= 0) {
  3442. menu_functions->insertSeparator(0);
  3443. }
  3444. for(size_t i = 0; i < recent_functions.size(); i++) {
  3445. if(recent_functions[i] == object) {
  3446. recent_functions.erase(recent_functions.begin() + i);
  3447. menu_functions->removeItem(recent_function_ids[i]);
  3448. recent_function_ids.erase(recent_function_ids.begin() + i);
  3449. break;
  3450. }
  3451. }
  3452. if(recent_function_ids.size() >= 5) {
  3453. recent_functions.erase(recent_functions.begin());
  3454. menu_functions->removeItem(recent_function_ids[0]);
  3455. recent_function_ids.erase(recent_function_ids.begin());
  3456. }
  3457. int id = menu_functions->insertItem(object->title(true).c_str(), -1, 0);
  3458. menu_functions_ids[id] = object;
  3459. recent_function_ids.push_back(id);
  3460. recent_functions.push_back(object);
  3461. }
  3462. void KQalculate::variable_inserted(Variable *object) {
  3463. if(!object) {
  3464. return;
  3465. }
  3466. if(recent_variable_ids.size() <= 0) {
  3467. menu_variables->insertSeparator(0);
  3468. }
  3469. for(size_t i = 0; i < recent_variables.size(); i++) {
  3470. if(recent_variables[i] == object) {
  3471. recent_variables.erase(recent_variables.begin() + i);
  3472. menu_variables->removeItem(recent_variable_ids[i]);
  3473. recent_variable_ids.erase(recent_variable_ids.begin() + i);
  3474. break;
  3475. }
  3476. }
  3477. if(recent_variable_ids.size() >= 5) {
  3478. recent_variables.erase(recent_variables.begin());
  3479. menu_variables->removeItem(recent_variable_ids[0]);
  3480. recent_variable_ids.erase(recent_variable_ids.begin());
  3481. }
  3482. int id = menu_variables->insertItem(object->title(true).c_str(), -1, 0);
  3483. menu_variables_ids[id] = object;
  3484. recent_variable_ids.push_back(id);
  3485. recent_variables.push_back(object);
  3486. }
  3487. void KQalculate::unit_inserted(Unit *object) {
  3488. if(!object) {
  3489. return;
  3490. }
  3491. if(recent_unit_ids.size() <= 0) {
  3492. menu_units->insertSeparator(0);
  3493. }
  3494. for(size_t i = 0; i < recent_units.size(); i++) {
  3495. if(recent_units[i] == object) {
  3496. recent_units.erase(recent_units.begin() + i);
  3497. menu_units->removeItem(recent_unit_ids[i]);
  3498. recent_unit_ids.erase(recent_unit_ids.begin() + i);
  3499. break;
  3500. }
  3501. }
  3502. if(recent_unit_ids.size() >= 5) {
  3503. recent_units.erase(recent_units.begin());
  3504. menu_units->removeItem(recent_unit_ids[0]);
  3505. recent_unit_ids.erase(recent_unit_ids.begin());
  3506. }
  3507. int id = menu_units->insertItem(object->title(true).c_str(), -1, 0);
  3508. menu_units_ids[id] = object;
  3509. recent_unit_ids.push_back(id);
  3510. recent_units.push_back(object);
  3511. }
  3512. void KQalculate::onVariableMenuItemActivated(int id) {
  3513. if(!menu_variables_ids.contains(id)) return;
  3514. Variable *v = menu_variables_ids[id];
  3515. if(!CALCULATOR->stillHasVariable(v)) {
  3516. KMessageBox::error(this, i18n("Variable does not exist anymore."));
  3517. update_vmenu();
  3518. return;
  3519. }
  3520. insert_text(v->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str());
  3521. variable_inserted(v);
  3522. }
  3523. void KQalculate::onFunctionMenuItemActivated(int id) {
  3524. if(!menu_functions_ids.contains(id)) return;
  3525. MathFunction *f = menu_functions_ids[id];
  3526. insertFunction(f, this);
  3527. }
  3528. void KQalculate::onUnitMenuItemActivated(int id) {
  3529. if(!menu_units_ids.contains(id)) return;
  3530. Unit *u = menu_units_ids[id];
  3531. if(!CALCULATOR->stillHasUnit(u)) {
  3532. KMessageBox::error(this, i18n("Unit does not exist anymore."));
  3533. update_umenus();
  3534. return;
  3535. }
  3536. if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) {
  3537. insert_text(((CompositeUnit*) u)->print(true, printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) expressionEdit).c_str());
  3538. } else {
  3539. insert_text(u->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, true, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str());
  3540. }
  3541. unit_inserted(u);
  3542. }
  3543. void KQalculate::onUnitsPrefixMenuItemActivated(int id) {
  3544. if(!menu_units_prefixes_ids.contains(id)) return;
  3545. insert_text(menu_units_prefixes_ids[id]->name(printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) expressionEdit).c_str());
  3546. }
  3547. void KQalculate::update_completion() {
  3548. expressionEdit->updateCompletion();
  3549. if(plot_dialog) {
  3550. plot_dialog->expressionEdit->updateCompletion();
  3551. }
  3552. }
  3553. void KQalculate::set_unicode_buttons() {
  3554. if(printops.use_unicode_signs) {
  3555. if(can_display_unicode_string_function(SIGN_MINUS, (void*) kpMinus)) kpMinus->setText(SIGN_MINUS);
  3556. else kpMinus->setText(MINUS);
  3557. if(can_display_unicode_string_function(SIGN_PLUS, (void*) kpPlus)) kpPlus->setText(SIGN_PLUS);
  3558. else kpPlus->setText(PLUS);
  3559. if(can_display_unicode_string_function(SIGN_MULTIPLICATION, (void*) kpTimes)) kpTimes->setText(SIGN_MULTIPLICATION);
  3560. else kpTimes->setText(MULTIPLICATION);
  3561. if(can_display_unicode_string_function(SIGN_DIVISION_SLASH, (void*) kpDivision)) kpDivision->setText(SIGN_DIVISION_SLASH);
  3562. else if(can_display_unicode_string_function(SIGN_DIVISION, (void*) kpDivision)) kpDivision->setText(SIGN_DIVISION);
  3563. else kpDivision->setText(DIVISION);
  3564. if(can_display_unicode_string_function(SIGN_SQRT, (void*) kpSqrt)) kpSqrt->setText(SIGN_SQRT);
  3565. else kpSqrt->setText("Sqrt");
  3566. if(can_display_unicode_string_function(SIGN_MULTIDOT, (void*) kpDot)) kpDot->setText(SIGN_MULTIDOT);
  3567. else kpDot->setText(CALCULATOR->getDecimalPoint().c_str());
  3568. } else {
  3569. kpMinus->setText(MINUS);
  3570. kpPlus->setText(PLUS);
  3571. kpTimes->setText(MULTIPLICATION);
  3572. kpDivision->setText(DIVISION);
  3573. kpSqrt->setText("Sqrt");
  3574. kpDot->setText(CALCULATOR->getDecimalPoint().c_str());
  3575. }
  3576. }
  3577. void KQalculate::onExpressionChanged() {
  3578. expression_has_changed = true;
  3579. expression_has_changed2 = true;
  3580. if(!rpn_mode) clearresult();
  3581. if(!expressionEdit->dont_change_index) expressionEdit->expression_history_index = -1;
  3582. displayParseStatus();
  3583. }
  3584. void KQalculate::execute() {
  3585. execute_expression_force = true;
  3586. execute_expression_do_stack = false;
  3587. execute_expression_do_mathoperation = false;
  3588. execute_expression2();
  3589. }
  3590. bool KQalculate::fetch_exchange_rates(int) {
  3591. KURL url(CALCULATOR->getExchangeRatesUrl().c_str());
  3592. QString filename(CALCULATOR->getExchangeRatesFileName().c_str());
  3593. #if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
  3594. if(KIO::NetAccess::download(url, filename)) {
  3595. #else
  3596. if(KIO::NetAccess::download(url, filename, this)) {
  3597. #endif
  3598. return true;
  3599. } else {
  3600. QString errorstr = i18n("Failed to download exchange rates from ECB.");
  3601. errorstr += "\n";
  3602. errorstr += KIO::NetAccess::lastErrorString();
  3603. KMessageBox::error(this, errorstr);
  3604. return false;
  3605. }
  3606. }
  3607. void KQalculate::onErrorTimeout() {
  3608. if(CALCULATOR->checkSaveFunctionCalled()) {
  3609. update_vmenu();
  3610. }
  3611. display_errors();
  3612. }
  3613. void KQalculate::toggleHistory(bool on) {
  3614. if(on) {
  3615. bool b = mainStack->isVisible();
  3616. int new_height = height();
  3617. if(bottomLine->isVisible()) new_height -= bottomLine->height();
  3618. if(mainStack->height() > history_height) history_height = mainStack->height();
  3619. bottomLine->hide();
  3620. mainStack->show();
  3621. mainStack->raiseWidget(1);
  3622. keypadButton->setOn(false);
  3623. stackButton->setOn(false);
  3624. mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
  3625. resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
  3626. if(!b) {
  3627. new_height += history_height;
  3628. resize(width(), new_height);
  3629. } else if(history_height != mainStack->height()) {
  3630. resize(width(), height() - mainStack->height() + history_height);
  3631. }
  3632. } else {
  3633. if(!keypadButton->isOn() && !stackButton->isOn()) {
  3634. history_height = mainStack->height();
  3635. int new_height = height() - mainStack->height();
  3636. mainStack->hide();
  3637. bottomLine->show();
  3638. qApp->processEvents();
  3639. if(new_height < height()) resize(width(), new_height + bottomLine->height());
  3640. mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
  3641. resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
  3642. }
  3643. }
  3644. }
  3645. void KQalculate::toggleStack(bool on) {
  3646. if(on) {
  3647. bool b = mainStack->isVisible();
  3648. int new_height = height();
  3649. if(bottomLine->isVisible()) new_height -= bottomLine->height();
  3650. if(mainStack->height() > history_height) history_height = mainStack->height();
  3651. bottomLine->hide();
  3652. mainStack->show();
  3653. mainStack->raiseWidget(2);
  3654. keypadButton->setOn(false);
  3655. historyButton->setOn(false);
  3656. mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
  3657. resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
  3658. if(!b) {
  3659. new_height += history_height;
  3660. resize(width(), new_height);
  3661. } else if(history_height != mainStack->height()) {
  3662. resize(width(), height() - mainStack->height() + history_height);
  3663. }
  3664. } else {
  3665. if(!keypadButton->isOn() && !historyButton->isOn()) {
  3666. history_height = mainStack->height();
  3667. int new_height = height() - mainStack->height();
  3668. mainStack->hide();
  3669. bottomLine->show();
  3670. qApp->processEvents();
  3671. if(new_height < height()) resize(width(), new_height + bottomLine->height());
  3672. mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
  3673. resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
  3674. }
  3675. }
  3676. }
  3677. void KQalculate::toggleKeypad(bool on) {
  3678. if(on) {
  3679. bool b = mainStack->isVisible();
  3680. if(b) history_height = mainStack->height();
  3681. int new_height = height() - bottomLine->height();
  3682. mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
  3683. resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
  3684. mainStack->show();
  3685. bottomLine->hide();
  3686. mainStack->raiseWidget(0);
  3687. historyButton->setOn(false);
  3688. stackButton->setOn(false);
  3689. if(!b) {
  3690. qApp->processEvents();
  3691. new_height += mainStack->height();
  3692. resize(width(), new_height);
  3693. } else {
  3694. resize(width(), minimumSizeHint().height());
  3695. }
  3696. } else {
  3697. if(!historyButton->isOn() && !stackButton->isOn()) {
  3698. int new_height = height() - mainStack->height();
  3699. mainStack->hide();
  3700. bottomLine->show();
  3701. qApp->processEvents();
  3702. if(new_height < height()) resize(width(), new_height + bottomLine->height());
  3703. mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
  3704. resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
  3705. }
  3706. }
  3707. }
  3708. void KQalculate::showHide() {
  3709. if(isVisible()) {
  3710. hide();
  3711. } else {
  3712. #if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
  3713. KWin::Info info = KWin::info(winId());
  3714. KWin::setOnDesktop(winId(), KWin::currentDesktop());
  3715. move(info.geometry.topLeft());
  3716. #else
  3717. KWin::WindowInfo info = KWin::windowInfo(winId(), (unsigned long) NET::WMGeometry);
  3718. KWin::setOnDesktop(winId(), KWin::currentDesktop());
  3719. move(info.geometry().topLeft());
  3720. #endif
  3721. setShown(true);
  3722. show();
  3723. raise();
  3724. #if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
  3725. KWin::setActiveWindow(winId());
  3726. #else
  3727. KWin::activateWindow(winId());
  3728. #endif
  3729. }
  3730. }
  3731. void KQalculate::configureGlobalShortcuts() {
  3732. KKeyDialog::configure(globalAccel, 0, false);
  3733. globalAccel->writeSettings();
  3734. globalAccel->updateConnections();
  3735. }
  3736. void KQalculate::abbreviateNames(bool b) {
  3737. printops.abbreviate_names = b;
  3738. result_format_updated();
  3739. }
  3740. void KQalculate::approximationAlwaysExact() {
  3741. kpExact->blockSignals(true);
  3742. evalops.approximation = APPROXIMATION_EXACT;
  3743. expression_calculation_updated();
  3744. kpExact->setOn(true);
  3745. kpExact->blockSignals(false);
  3746. }
  3747. void KQalculate::approximationTryExact() {
  3748. kpExact->blockSignals(true);
  3749. evalops.approximation = APPROXIMATION_TRY_EXACT;
  3750. expression_calculation_updated();
  3751. kpExact->setOn(false);
  3752. kpExact->blockSignals(false);
  3753. }
  3754. void KQalculate::approximationApproximate() {
  3755. kpExact->blockSignals(true);
  3756. evalops.approximation = APPROXIMATION_APPROXIMATE;
  3757. expression_calculation_updated();
  3758. kpExact->setOn(false);
  3759. kpExact->blockSignals(false);
  3760. }
  3761. void KQalculate::fractionalDisplayDecimal() {
  3762. kpFraction->blockSignals(true);
  3763. printops.number_fraction_format = FRACTION_DECIMAL;
  3764. result_format_updated();
  3765. kpFraction->setOn(false);
  3766. kpFraction->blockSignals(false);
  3767. }
  3768. void KQalculate::fractionalDisplayDecimalTryExact() {
  3769. kpFraction->blockSignals(true);
  3770. printops.number_fraction_format = FRACTION_DECIMAL_EXACT;
  3771. result_format_updated();
  3772. kpFraction->setOn(false);
  3773. kpFraction->blockSignals(false);
  3774. }
  3775. void KQalculate::fractionalDisplayFraction() {
  3776. kpFraction->blockSignals(true);
  3777. printops.number_fraction_format = FRACTION_FRACTIONAL;
  3778. result_format_updated();
  3779. kpFraction->setOn(true);
  3780. kpFraction->blockSignals(false);
  3781. }
  3782. void KQalculate::fractionalDisplayCombined() {
  3783. kpFraction->blockSignals(true);
  3784. printops.number_fraction_format = FRACTION_COMBINED;
  3785. result_format_updated();
  3786. kpFraction->setOn(true);
  3787. kpFraction->blockSignals(false);
  3788. }
  3789. void KQalculate::numericalDisplayNormal() {
  3790. kpNumericCombo->blockSignals(true);
  3791. printops.min_exp = EXP_PRECISION;
  3792. result_format_updated();
  3793. kpNumericCombo->setCurrentItem(0);
  3794. kpNumericCombo->blockSignals(false);
  3795. }
  3796. void KQalculate::numericalDisplayEngineering() {
  3797. kpNumericCombo->blockSignals(true);
  3798. printops.min_exp = EXP_BASE_3;
  3799. result_format_updated();
  3800. kpNumericCombo->setCurrentItem(1);
  3801. kpNumericCombo->blockSignals(false);
  3802. }
  3803. void KQalculate::numericalDisplayScientific() {
  3804. kpNumericCombo->blockSignals(true);
  3805. printops.min_exp = EXP_SCIENTIFIC;
  3806. result_format_updated();
  3807. kpNumericCombo->setCurrentItem(2);
  3808. kpNumericCombo->blockSignals(false);
  3809. }
  3810. void KQalculate::numericalDisplayPurelyScientific() {
  3811. kpNumericCombo->blockSignals(true);
  3812. printops.min_exp = EXP_PURE;
  3813. result_format_updated();
  3814. kpNumericCombo->setCurrentItem(3);
  3815. kpNumericCombo->blockSignals(false);
  3816. }
  3817. void KQalculate::numericalDisplaySimple() {
  3818. kpNumericCombo->blockSignals(true);
  3819. printops.min_exp = EXP_NONE;
  3820. result_format_updated();
  3821. kpNumericCombo->setCurrentItem(4);
  3822. kpNumericCombo->blockSignals(false);
  3823. }
  3824. void KQalculate::roundHalfwayNumbersToEven(bool b) {
  3825. printops.round_halfway_to_even = b;
  3826. result_format_updated();
  3827. }
  3828. void KQalculate::indicateInfiniteSeries(bool b) {
  3829. printops.indicate_infinite_series = b;
  3830. result_format_updated();
  3831. }
  3832. void KQalculate::sortMinusLast(bool b) {
  3833. printops.sort_options.minus_last = b;
  3834. result_format_updated();
  3835. }
  3836. void KQalculate::negativeExponents(bool b) {
  3837. printops.negative_exponents = b;
  3838. result_format_updated();
  3839. }
  3840. void KQalculate::showEndingZeroes(bool b) {
  3841. printops.show_ending_zeroes = b;
  3842. result_format_updated();
  3843. }
  3844. void KQalculate::updateBaseOther() {
  3845. if(set_base_dialog) {
  3846. set_base_dialog->outputBaseBox->blockSignals(true);
  3847. set_base_dialog->radiogroup_output->blockSignals(true);
  3848. set_base_dialog->outputBaseBox->setEnabled(false);
  3849. switch(printops.base) {
  3850. case BASE_BINARY: {
  3851. set_base_dialog->radiogroup_output->setButton(0);
  3852. break;
  3853. }
  3854. case BASE_OCTAL: {
  3855. set_base_dialog->radiogroup_output->setButton(1);
  3856. break;
  3857. }
  3858. case BASE_DECIMAL: {
  3859. set_base_dialog->radiogroup_output->setButton(2);
  3860. break;
  3861. }
  3862. case BASE_HEXADECIMAL: {
  3863. set_base_dialog->radiogroup_output->setButton(3);
  3864. break;
  3865. }
  3866. case BASE_SEXAGESIMAL: {
  3867. set_base_dialog->radiogroup_output->setButton(5);
  3868. break;
  3869. }
  3870. case BASE_TIME: {
  3871. set_base_dialog->radiogroup_output->setButton(6);
  3872. break;
  3873. }
  3874. case BASE_ROMAN_NUMERALS: {
  3875. set_base_dialog->radiogroup_output->setButton(7);
  3876. break;
  3877. }
  3878. default: {
  3879. set_base_dialog->radiogroup_output->setButton(4);
  3880. set_base_dialog->outputBaseBox->setEnabled(true);
  3881. set_base_dialog->outputBaseBox->setValue(printops.base);
  3882. }
  3883. }
  3884. set_base_dialog->outputBaseBox->blockSignals(false);
  3885. set_base_dialog->radiogroup_output->blockSignals(false);
  3886. }
  3887. }
  3888. void KQalculate::numberBaseBinary() {
  3889. kpBaseCombo->blockSignals(true);
  3890. printops.base = BASE_BINARY;
  3891. updateBaseOther();
  3892. result_format_updated();
  3893. kpBaseCombo->setCurrentItem(0);
  3894. kpBaseCombo->blockSignals(false);
  3895. }
  3896. void KQalculate::numberBaseOctal() {
  3897. kpBaseCombo->blockSignals(true);
  3898. printops.base = BASE_OCTAL;
  3899. updateBaseOther();
  3900. result_format_updated();
  3901. kpBaseCombo->setCurrentItem(1);
  3902. kpBaseCombo->blockSignals(false);
  3903. }
  3904. void KQalculate::numberBaseDecimal() {
  3905. kpBaseCombo->blockSignals(true);
  3906. printops.base = BASE_DECIMAL;
  3907. updateBaseOther();
  3908. result_format_updated();
  3909. kpBaseCombo->setCurrentItem(2);
  3910. kpBaseCombo->blockSignals(false);
  3911. }
  3912. void KQalculate::numberBaseHexadecimal() {
  3913. kpBaseCombo->blockSignals(true);
  3914. printops.base = BASE_HEXADECIMAL;
  3915. updateBaseOther();
  3916. result_format_updated();
  3917. kpBaseCombo->setCurrentItem(3);
  3918. kpBaseCombo->blockSignals(false);
  3919. }
  3920. void KQalculate::numberBaseSexagesimal() {
  3921. kpBaseCombo->blockSignals(true);
  3922. printops.base = BASE_SEXAGESIMAL;
  3923. updateBaseOther();
  3924. result_format_updated();
  3925. kpBaseCombo->setCurrentItem(4);
  3926. kpBaseCombo->blockSignals(false);
  3927. }
  3928. void KQalculate::numberBaseTimeFormat() {
  3929. kpBaseCombo->blockSignals(true);
  3930. printops.base = BASE_TIME;
  3931. updateBaseOther();
  3932. result_format_updated();
  3933. kpBaseCombo->setCurrentItem(5);
  3934. kpBaseCombo->blockSignals(false);
  3935. }
  3936. void KQalculate::numberBaseRomanNumerals() {
  3937. kpBaseCombo->blockSignals(true);
  3938. printops.base = BASE_ROMAN_NUMERALS;
  3939. updateBaseOther();
  3940. result_format_updated();
  3941. kpBaseCombo->setCurrentItem(6);
  3942. kpBaseCombo->blockSignals(false);
  3943. }
  3944. void KQalculate::numberBaseOther() {
  3945. setBase();
  3946. set_base_dialog->radiogroup_output->setButton(4);
  3947. setBaseInResultFromDialogGroup(4);
  3948. set_base_dialog->outputBaseBox->setFocus();
  3949. setBaseInResultFromDialogBox(set_base_dialog->outputBaseBox->value());
  3950. }
  3951. void KQalculate::setBaseInExpressionFromDialogBox(int value) {
  3952. evalops.parse_options.base = value;
  3953. expression_format_updated(true);
  3954. }
  3955. void KQalculate::setBaseInExpressionFromDialogGroup(int id) {
  3956. switch(id) {
  3957. case 0: {
  3958. set_base_dialog->inputBaseBox->setEnabled(false);
  3959. evalops.parse_options.base = BASE_BINARY;
  3960. break;
  3961. }
  3962. case 1: {
  3963. set_base_dialog->inputBaseBox->setEnabled(false);
  3964. evalops.parse_options.base = BASE_OCTAL;
  3965. break;
  3966. }
  3967. case 2: {
  3968. set_base_dialog->inputBaseBox->setEnabled(false);
  3969. evalops.parse_options.base = BASE_DECIMAL;
  3970. break;
  3971. }
  3972. case 3: {
  3973. set_base_dialog->inputBaseBox->setEnabled(false);
  3974. evalops.parse_options.base = BASE_HEXADECIMAL;
  3975. break;
  3976. }
  3977. case 4: {
  3978. set_base_dialog->inputBaseBox->setEnabled(true);
  3979. evalops.parse_options.base = set_base_dialog->inputBaseBox->value();
  3980. break;
  3981. }
  3982. case 5: {
  3983. set_base_dialog->inputBaseBox->setEnabled(false);
  3984. evalops.parse_options.base = BASE_ROMAN_NUMERALS;
  3985. break;
  3986. }
  3987. }
  3988. expression_format_updated(true);
  3989. }
  3990. void KQalculate::setBaseInResultFromDialogBox(int value) {
  3991. bool b = (printops.base == value);
  3992. printops.base = value;
  3993. kpBaseCombo->blockSignals(true);
  3994. switch(value) {
  3995. case BASE_BINARY: {
  3996. ActionNumberBaseBinary->setChecked(true);
  3997. kpBaseCombo->setCurrentItem(0);
  3998. break;
  3999. }
  4000. case BASE_OCTAL: {
  4001. ActionNumberBaseOctal->setChecked(true);
  4002. kpBaseCombo->setCurrentItem(1);
  4003. break;
  4004. }
  4005. case BASE_DECIMAL: {
  4006. ActionNumberBaseDecimal->setChecked(true);
  4007. kpBaseCombo->setCurrentItem(2);
  4008. break;
  4009. }
  4010. case BASE_HEXADECIMAL: {
  4011. ActionNumberBaseHexadecimal->setChecked(true);
  4012. kpBaseCombo->setCurrentItem(3);
  4013. break;
  4014. }
  4015. default: {
  4016. ActionNumberBaseOther->setChecked(true);
  4017. kpBaseCombo->setCurrentItem(7);
  4018. break;
  4019. }
  4020. }
  4021. kpBaseCombo->blockSignals(false);
  4022. if(!b) result_format_updated();
  4023. }
  4024. void KQalculate::setBaseInResultFromDialogGroup(int id) {
  4025. switch(id) {
  4026. case 0: {
  4027. set_base_dialog->outputBaseBox->setEnabled(false);
  4028. ActionNumberBaseBinary->activate();
  4029. break;
  4030. }
  4031. case 1: {
  4032. set_base_dialog->outputBaseBox->setEnabled(false);
  4033. ActionNumberBaseOctal->activate();
  4034. break;
  4035. }
  4036. case 2: {
  4037. set_base_dialog->outputBaseBox->setEnabled(false);
  4038. ActionNumberBaseDecimal->activate();
  4039. break;
  4040. }
  4041. case 3: {
  4042. set_base_dialog->outputBaseBox->setEnabled(false);
  4043. ActionNumberBaseHexadecimal->activate();
  4044. break;
  4045. }
  4046. case 4: {
  4047. set_base_dialog->outputBaseBox->setEnabled(true);
  4048. ActionNumberBaseOther->setChecked(true);
  4049. kpBaseCombo->blockSignals(true);
  4050. bool b = (printops.base == set_base_dialog->outputBaseBox->value());
  4051. printops.base = set_base_dialog->outputBaseBox->value();
  4052. kpBaseCombo->setCurrentItem(7);
  4053. kpBaseCombo->blockSignals(false);
  4054. if(!b) result_format_updated();
  4055. break;
  4056. }
  4057. case 5: {
  4058. set_base_dialog->outputBaseBox->setEnabled(false);
  4059. ActionNumberBaseSexagesimal->activate();
  4060. break;
  4061. }
  4062. case 6: {
  4063. set_base_dialog->outputBaseBox->setEnabled(false);
  4064. ActionNumberBaseTimeFormat->activate();
  4065. break;
  4066. }
  4067. case 7: {
  4068. set_base_dialog->outputBaseBox->setEnabled(false);
  4069. ActionNumberBaseRomanNumerals->activate();
  4070. break;
  4071. }
  4072. }
  4073. }
  4074. void KQalculate::setBase() {
  4075. if(!set_base_dialog) {
  4076. set_base_dialog = new QalculateSetBaseDialog(this);
  4077. QObject::connect(set_base_dialog->radiogroup_input, SIGNAL(clicked(int)), this, SLOT(setBaseInExpressionFromDialogGroup(int)));
  4078. QObject::connect(set_base_dialog->inputBaseBox, SIGNAL(valueChanged(int)), this, SLOT(setBaseInExpressionFromDialogBox(int)));
  4079. QObject::connect(set_base_dialog->radiogroup_output, SIGNAL(clicked(int)), this, SLOT(setBaseInResultFromDialogGroup(int)));
  4080. QObject::connect(set_base_dialog->outputBaseBox, SIGNAL(valueChanged(int)), this, SLOT(setBaseInResultFromDialogBox(int)));
  4081. }
  4082. set_base_dialog->inputBaseBox->blockSignals(true);
  4083. set_base_dialog->radiogroup_input->blockSignals(true);
  4084. set_base_dialog->inputBaseBox->setEnabled(false);
  4085. switch(evalops.parse_options.base) {
  4086. case BASE_BINARY: {
  4087. set_base_dialog->radiogroup_input->setButton(0);
  4088. break;
  4089. }
  4090. case BASE_OCTAL: {
  4091. set_base_dialog->radiogroup_input->setButton(1);
  4092. break;
  4093. }
  4094. case BASE_DECIMAL: {
  4095. set_base_dialog->radiogroup_input->setButton(2);
  4096. break;
  4097. }
  4098. case BASE_HEXADECIMAL: {
  4099. set_base_dialog->radiogroup_input->setButton(3);
  4100. break;
  4101. }
  4102. case BASE_ROMAN_NUMERALS: {
  4103. set_base_dialog->radiogroup_input->setButton(5);
  4104. break;
  4105. }
  4106. default: {
  4107. set_base_dialog->radiogroup_input->setButton(4);
  4108. set_base_dialog->inputBaseBox->setEnabled(true);
  4109. set_base_dialog->inputBaseBox->setValue(evalops.parse_options.base);
  4110. }
  4111. }
  4112. set_base_dialog->inputBaseBox->blockSignals(false);
  4113. set_base_dialog->radiogroup_input->blockSignals(false);
  4114. updateBaseOther();
  4115. set_base_dialog->show();
  4116. }
  4117. void KQalculate::nonZeroDenominators(bool b) {
  4118. evalops.assume_denominators_nonzero = b;
  4119. expression_calculation_updated();
  4120. }
  4121. void KQalculate::warnAboutDenominatorsAssumedNonZero(bool b) {
  4122. evalops.warn_about_denominators_assumed_nonzero = b;
  4123. if(evalops.warn_about_denominators_assumed_nonzero) expression_calculation_updated();
  4124. }
  4125. void KQalculate::readPrecision(bool b) {
  4126. if(b) evalops.parse_options.read_precision = READ_PRECISION_WHEN_DECIMALS;
  4127. else evalops.parse_options.read_precision = DONT_READ_PRECISION;
  4128. expression_format_updated(true);
  4129. }
  4130. void KQalculate::limitImplicitMultiplication(bool b) {
  4131. evalops.parse_options.limit_implicit_multiplication = b;
  4132. printops.limit_implicit_multiplication = b;
  4133. expression_format_updated(true);
  4134. result_format_updated();
  4135. }
  4136. void KQalculate::rpnMode(bool b) {
  4137. if(b == rpn_mode) return;
  4138. rpn_mode = b;
  4139. if(rpn_mode) {
  4140. stackButton->show();
  4141. show_history = historyButton->isOn();
  4142. show_keypad = keypadButton->isOn();
  4143. if(show_stack) {
  4144. stackButton->toggle();
  4145. }
  4146. } else {
  4147. show_stack = stackButton->isOn();
  4148. if(show_stack) {
  4149. if(show_history) historyButton->toggle();
  4150. else if(show_keypad) keypadButton->toggle();
  4151. else stackButton->toggle();
  4152. }
  4153. stackButton->hide();
  4154. CALCULATOR->clearRPNStack();
  4155. stackList->clear();
  4156. }
  4157. if(leftButtonsSeparator->isVisible()) {
  4158. if(rpn_mode) executeButton->setText(i18n("Enter"));
  4159. else executeButton->setText(i18n("="));
  4160. }
  4161. if(rpn_mode) {
  4162. kpEquals->setText(i18n("Ent"));
  4163. QToolTip::add(kpEquals, i18n("Calculate expression and add to stack"));
  4164. QToolTip::add(executeButton, i18n("Calculate expression and add to stack"));
  4165. } else {
  4166. kpEquals->setText(i18n("="));
  4167. QToolTip::add(kpEquals, i18n("Calculate expression"));
  4168. QToolTip::add(executeButton, i18n("Calculate expression"));
  4169. }
  4170. }
  4171. void KQalculate::rpnSyntax(bool b) {
  4172. evalops.parse_options.rpn = b;
  4173. expression_format_updated(false);
  4174. }
  4175. void KQalculate::setMinDecimals(int i) {
  4176. printops.min_decimals = i;
  4177. if(i <= 0) printops.use_min_decimals = false;
  4178. else printops.use_min_decimals = true;
  4179. result_format_updated();
  4180. }
  4181. void KQalculate::setMaxDecimals(int i) {
  4182. printops.max_decimals = i;
  4183. if(i < 0) printops.use_max_decimals = false;
  4184. else printops.use_max_decimals = true;
  4185. result_format_updated();
  4186. }
  4187. void KQalculate::decimals() {
  4188. if(!decimalsDialog) {
  4189. decimalsDialog = new QalculateDecimalsDialog(this);
  4190. QObject::connect(decimalsDialog->minDecimalsBox, SIGNAL(valueChanged(int)), this, SLOT(setMinDecimals(int)));
  4191. QObject::connect(decimalsDialog->maxDecimalsBox, SIGNAL(valueChanged(int)), this, SLOT(setMaxDecimals(int)));
  4192. }
  4193. decimalsDialog->minDecimalsBox->blockSignals(true);
  4194. decimalsDialog->maxDecimalsBox->blockSignals(true);
  4195. if(printops.use_min_decimals && printops.min_decimals > 0) decimalsDialog->minDecimalsBox->setValue(printops.min_decimals);
  4196. else decimalsDialog->minDecimalsBox->setValue(0);
  4197. if(printops.use_max_decimals && printops.max_decimals >= 0) decimalsDialog->maxDecimalsBox->setValue(printops.max_decimals);
  4198. else decimalsDialog->maxDecimalsBox->setValue(-1);
  4199. decimalsDialog->minDecimalsBox->blockSignals(false);
  4200. decimalsDialog->maxDecimalsBox->blockSignals(false);
  4201. decimalsDialog->show();
  4202. }
  4203. void KQalculate::setPrecision(int i) {
  4204. if(i != CALCULATOR->getPrecision()) CALCULATOR->setPrecision(i);
  4205. }
  4206. void KQalculate::precision() {
  4207. if(!precisionDialog) {
  4208. precisionDialog = new QalculatePrecisionDialog(this);
  4209. QObject::connect(precisionDialog, SIGNAL(applyClicked()), this, SLOT(precisionRecalculate()));
  4210. QObject::connect(precisionDialog->precisionBox, SIGNAL(valueChanged(int)), this, SLOT(setPrecision(int)));
  4211. }
  4212. precisionDialog->precisionBox->setValue(CALCULATOR->getPrecision());
  4213. precisionDialog->show();
  4214. }
  4215. void KQalculate::precisionRecalculate() {
  4216. if(precisionDialog->precisionBox->value() != CALCULATOR->getPrecision()) CALCULATOR->setPrecision(precisionDialog->precisionBox->value());
  4217. expression_calculation_updated();
  4218. }
  4219. void KQalculate::assumptionTypeUnknown() {
  4220. CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_NONE);
  4221. setAssumptionsMenu();
  4222. expression_calculation_updated();
  4223. }
  4224. void KQalculate::assumptionTypeNonMatrix() {
  4225. CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_NONMATRIX);
  4226. setAssumptionsMenu();
  4227. expression_calculation_updated();
  4228. }
  4229. void KQalculate::assumptionTypeNumber() {
  4230. CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_NUMBER);
  4231. setAssumptionsMenu();
  4232. expression_calculation_updated();
  4233. }
  4234. void KQalculate::assumptionTypeComplex() {
  4235. CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_COMPLEX);
  4236. setAssumptionsMenu();
  4237. expression_calculation_updated();
  4238. }
  4239. void KQalculate::assumptionTypeReal() {
  4240. CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_REAL);
  4241. setAssumptionsMenu();
  4242. expression_calculation_updated();
  4243. }
  4244. void KQalculate::assumptionTypeRational() {
  4245. CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_RATIONAL);
  4246. setAssumptionsMenu();
  4247. expression_calculation_updated();
  4248. }
  4249. void KQalculate::assumptionTypeInteger() {
  4250. CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_INTEGER);
  4251. setAssumptionsMenu();
  4252. expression_calculation_updated();
  4253. }
  4254. void KQalculate::assumptionSignUnknown() {
  4255. CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_UNKNOWN);
  4256. setAssumptionsMenu();
  4257. expression_calculation_updated();
  4258. }
  4259. void KQalculate::assumptionSignNonZero() {
  4260. CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_NONZERO);
  4261. setAssumptionsMenu();
  4262. expression_calculation_updated();
  4263. }
  4264. void KQalculate::assumptionSignPositive() {
  4265. CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_POSITIVE);
  4266. setAssumptionsMenu();
  4267. expression_calculation_updated();
  4268. }
  4269. void KQalculate::assumptionSignNonNegative() {
  4270. CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_NONNEGATIVE);
  4271. setAssumptionsMenu();
  4272. expression_calculation_updated();
  4273. }
  4274. void KQalculate::assumptionSignNegative() {
  4275. CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_NEGATIVE);
  4276. setAssumptionsMenu();
  4277. expression_calculation_updated();
  4278. }
  4279. void KQalculate::assumptionSignNonPositive() {
  4280. CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_NONPOSITIVE);
  4281. setAssumptionsMenu();
  4282. expression_calculation_updated();
  4283. }
  4284. void KQalculate::algebraicModeSimplify() {
  4285. evalops.structuring = STRUCTURING_SIMPLIFY;
  4286. printops.allow_factorization = false;
  4287. expression_calculation_updated();
  4288. }
  4289. void KQalculate::algebraicModeFactorize() {
  4290. evalops.structuring = STRUCTURING_FACTORIZE;
  4291. printops.allow_factorization = true;
  4292. expression_calculation_updated();
  4293. }
  4294. void KQalculate::algebraicModeNone() {
  4295. evalops.structuring = STRUCTURING_NONE;
  4296. printops.allow_factorization = false;
  4297. expression_calculation_updated();
  4298. }
  4299. void KQalculate::onModesMenuItemActivated(int id) {
  4300. loadMode(menu_modes->indexOf(id));
  4301. }
  4302. void KQalculate::loadMode(int index) {
  4303. if(index < 0) return;
  4304. size_t i = (size_t) index;
  4305. if(i >= modes.size()) return;
  4306. printops.min_decimals = modes[i].po.min_decimals;
  4307. printops.use_min_decimals = modes[i].po.use_min_decimals;
  4308. printops.max_decimals = modes[i].po.max_decimals;
  4309. printops.use_max_decimals = modes[i].po.use_max_decimals;
  4310. CALCULATOR->setPrecision(modes[i].precision);
  4311. printops.min_exp = modes[i].po.min_exp;
  4312. printops.negative_exponents = modes[i].po.negative_exponents;
  4313. printops.sort_options.minus_last = modes[i].po.sort_options.minus_last;
  4314. printops.number_fraction_format = modes[i].po.number_fraction_format;
  4315. printops.use_unit_prefixes = modes[i].po.use_unit_prefixes;
  4316. printops.abbreviate_names = modes[i].po.abbreviate_names;
  4317. printops.use_all_prefixes = modes[i].po.use_all_prefixes;
  4318. printops.use_denominator_prefix = modes[i].po.use_denominator_prefix;
  4319. printops.place_units_separately = modes[i].po.place_units_separately;
  4320. evalops.auto_post_conversion = modes[i].eo.auto_post_conversion;
  4321. printops.base = modes[i].po.base;
  4322. evalops.parse_options.base = modes[i].eo.parse_options.base;
  4323. evalops.parse_options.read_precision = modes[i].eo.parse_options.read_precision;
  4324. evalops.assume_denominators_nonzero = modes[i].eo.assume_denominators_nonzero;
  4325. evalops.warn_about_denominators_assumed_nonzero = modes[i].eo.warn_about_denominators_assumed_nonzero;
  4326. evalops.parse_options.angle_unit = modes[i].eo.parse_options.angle_unit;
  4327. evalops.parse_options.functions_enabled = modes[i].eo.parse_options.functions_enabled;
  4328. evalops.parse_options.variables_enabled = modes[i].eo.parse_options.variables_enabled;
  4329. evalops.calculate_functions = modes[i].eo.calculate_functions;
  4330. evalops.calculate_variables = modes[i].eo.calculate_variables;
  4331. evalops.sync_units = modes[i].eo.sync_units;
  4332. evalops.parse_options.unknowns_enabled = modes[i].eo.parse_options.unknowns_enabled;
  4333. evalops.parse_options.units_enabled = modes[i].eo.parse_options.units_enabled;
  4334. evalops.allow_complex = modes[i].eo.allow_complex;
  4335. evalops.allow_infinite = modes[i].eo.allow_infinite;
  4336. evalops.structuring = modes[i].eo.structuring;
  4337. printops.indicate_infinite_series = modes[i].po.indicate_infinite_series;
  4338. printops.show_ending_zeroes = modes[i].po.show_ending_zeroes;
  4339. printops.round_halfway_to_even = modes[i].po.round_halfway_to_even;
  4340. evalops.approximation = modes[i].eo.approximation;
  4341. evalops.parse_options.rpn = modes[i].eo.parse_options.rpn;
  4342. evalops.parse_options.limit_implicit_multiplication = modes[i].eo.parse_options.limit_implicit_multiplication;
  4343. printops.limit_implicit_multiplication = modes[i].po.limit_implicit_multiplication;
  4344. printops.spacious = modes[i].po.spacious;
  4345. printops.excessive_parenthesis = modes[i].po.excessive_parenthesis;
  4346. printops.short_multiplication = modes[i].po.short_multiplication;
  4347. CALCULATOR->defaultAssumptions()->setType(modes[i].at);
  4348. CALCULATOR->defaultAssumptions()->setSign(modes[i].as);
  4349. if(modes[i].rpn_mode != rpn_mode) {
  4350. rpnMode(modes[i].rpn_mode);
  4351. }
  4352. setModeActions();
  4353. if(decimalsDialog) {
  4354. decimalsDialog->minDecimalsBox->blockSignals(true);
  4355. decimalsDialog->maxDecimalsBox->blockSignals(true);
  4356. if(printops.use_min_decimals && printops.min_decimals > 0) decimalsDialog->minDecimalsBox->setValue(printops.min_decimals);
  4357. else decimalsDialog->minDecimalsBox->setValue(0);
  4358. if(printops.use_max_decimals && printops.max_decimals >= 0) decimalsDialog->maxDecimalsBox->setValue(printops.max_decimals);
  4359. else decimalsDialog->maxDecimalsBox->setValue(-1);
  4360. decimalsDialog->minDecimalsBox->blockSignals(false);
  4361. decimalsDialog->maxDecimalsBox->blockSignals(false);
  4362. }
  4363. if(precisionDialog) {
  4364. precisionDialog->precisionBox->setValue(CALCULATOR->getPrecision());
  4365. }
  4366. updateBaseOther();
  4367. if(set_base_dialog) {
  4368. set_base_dialog->inputBaseBox->blockSignals(true);
  4369. set_base_dialog->radiogroup_input->blockSignals(true);
  4370. set_base_dialog->inputBaseBox->setEnabled(false);
  4371. switch(evalops.parse_options.base) {
  4372. case BASE_BINARY: {
  4373. set_base_dialog->radiogroup_input->setButton(0);
  4374. break;
  4375. }
  4376. case BASE_OCTAL: {
  4377. set_base_dialog->radiogroup_input->setButton(1);
  4378. break;
  4379. }
  4380. case BASE_DECIMAL: {
  4381. set_base_dialog->radiogroup_input->setButton(2);
  4382. break;
  4383. }
  4384. case BASE_HEXADECIMAL: {
  4385. set_base_dialog->radiogroup_input->setButton(3);
  4386. break;
  4387. }
  4388. case BASE_ROMAN_NUMERALS: {
  4389. set_base_dialog->radiogroup_input->setButton(5);
  4390. break;
  4391. }
  4392. default: {
  4393. set_base_dialog->radiogroup_input->setButton(4);
  4394. set_base_dialog->inputBaseBox->setEnabled(true);
  4395. set_base_dialog->inputBaseBox->setValue(evalops.parse_options.base);
  4396. }
  4397. }
  4398. set_base_dialog->inputBaseBox->blockSignals(false);
  4399. set_base_dialog->radiogroup_input->blockSignals(false);
  4400. }
  4401. update_status_text();
  4402. printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
  4403. QString str = expressionEdit->text().stripWhiteSpace();
  4404. if(expression_has_changed || str.isEmpty()) {
  4405. setResult(NULL, true, false, false);
  4406. } else {
  4407. execute_expression(false);
  4408. }
  4409. expression_has_changed2 = true;
  4410. displayParseStatus();
  4411. expressionEdit->setFocus();
  4412. }
  4413. QalculateModeDialog::QalculateModeDialog(QWidget *parent) : KDialogBase(parent, 0, true, i18n("Save Mode"), KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok, true) {
  4414. setMainWidget(new QWidget(this));
  4415. QGridLayout *grid = new QGridLayout(mainWidget(), 2, 2, 0, spacingHint());
  4416. grid->addWidget(new QLabel(i18n("Mode name:"), mainWidget()), 0, 0);
  4417. modeCombo = new KComboBox(mainWidget());
  4418. modeCombo->setEditable(true);
  4419. for(size_t i = 2; i < modes.size(); i++) {
  4420. modeCombo->insertItem(modes[i].name);
  4421. }
  4422. modeCombo->lineEdit()->clear();
  4423. modeCombo->setFocus();
  4424. modeCombo->setSizePolicy(QSizePolicy::Expanding, modeCombo->sizePolicy().verData());
  4425. grid->addWidget(modeCombo, 0, 1);
  4426. grid->addWidget(new QLabel(i18n("Shortcut:"), mainWidget()), 1, 0);
  4427. keyButton = new KKeyButton(mainWidget());
  4428. grid->addWidget(keyButton, 1, 1);
  4429. connect(keyButton, SIGNAL(capturedShortcut(const KShortcut&)), this, SLOT(updateShortcut(const KShortcut&)));
  4430. connect(modeCombo, SIGNAL(activated(int)), this, SLOT(modeSelected(int)));
  4431. }
  4432. QalculateModeDialog::~QalculateModeDialog() {}
  4433. void QalculateModeDialog::modeSelected(int index) {
  4434. index += 2;
  4435. if(index < (int) modes.size()) {
  4436. keyButton->setShortcut(modes[index].shortcut, false);
  4437. }
  4438. }
  4439. void QalculateModeDialog::updateShortcut(const KShortcut &shortcut) {
  4440. keyButton->setShortcut(shortcut, false);
  4441. }
  4442. QString QalculateModeDialog::modeName() {
  4443. return modeCombo->currentText();
  4444. }
  4445. const KShortcut &QalculateModeDialog::modeShortcut() {
  4446. return keyButton->shortcut();
  4447. }
  4448. void QalculateModeDialog::slotOk() {
  4449. QString name = modeName();
  4450. if(name.isEmpty()) {
  4451. KMessageBox::error(this, i18n("Empty mode name."));
  4452. return;
  4453. } else if(name == modes[0].name) {
  4454. KMessageBox::error(this, i18n("Preset mode cannot be overwritten."));
  4455. return;
  4456. }
  4457. KDialogBase::slotOk();
  4458. }
  4459. void KQalculate::saveModeAs() {
  4460. QalculateModeDialog *dialog = new QalculateModeDialog(this);
  4461. if(dialog->exec() == QDialog::Accepted) {
  4462. bool new_mode = true;
  4463. QString name = dialog->modeName().stripWhiteSpace();
  4464. size_t index = save_mode_as(name, &new_mode);
  4465. modes[index].shortcut = dialog->modeShortcut();
  4466. if(new_mode) {
  4467. menu_modes->insertItem(modes[index].name, -1, index);
  4468. ActionDeleteMode->setEnabled(true);
  4469. ModeObject *mo = new ModeObject(index);
  4470. mo->i_mode = index;
  4471. mode_objects.push_back(mo);
  4472. accel()->insert(QString("Load mode: ") + modes[index].name, i18n("Load meta mode: %1").arg(modes[index].name), QString::null, modes[index].shortcut, mo, SLOT(loadMode()));
  4473. } else {
  4474. accel()->setShortcut(QString("Load mode: ") + modes[index].name, modes[index].shortcut);
  4475. }
  4476. }
  4477. delete dialog;
  4478. }
  4479. void KQalculate::deleteMode() {
  4480. #if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 2
  4481. bool b_ok = false;
  4482. QStringList mode_names;
  4483. for(size_t i = 2; i < modes.size(); i++) {
  4484. mode_names += modes[i].name;
  4485. }
  4486. QString name = KInputDialog::getItem(i18n("Delete Mode"), i18n("Mode:"), mode_names, 0, false, &b_ok, this).stripWhiteSpace();
  4487. if(b_ok) {
  4488. for(size_t i = 2; i < modes.size(); i++) {
  4489. if(modes[i].name == name) {
  4490. accel()->remove(QString("Load mode: ") + name);
  4491. modes.erase(modes.begin() + i);
  4492. delete mode_objects[i - 2];
  4493. mode_objects.erase(mode_objects.begin() + (i - 2));
  4494. for(QValueVector<ModeObject*>::size_type i2 = 0; i2 < mode_objects.size(); i2++) {
  4495. mode_objects[i2]->i_mode = i2 + 2;
  4496. }
  4497. menu_modes->removeItemAt(i);
  4498. if(modes.size() < 3) {
  4499. ActionDeleteMode->setEnabled(false);
  4500. }
  4501. }
  4502. }
  4503. }
  4504. #endif
  4505. }
  4506. void KQalculate::saveMode() {
  4507. save_mode();
  4508. }
  4509. void KQalculate::aboutToQuit() {
  4510. if(plot_dialog) plot_dialog->saveMode();
  4511. if(save_mode_on_exit) {
  4512. save_mode();
  4513. } else {
  4514. save_preferences();
  4515. }
  4516. if(save_defs_on_exit) {
  4517. save_defs();
  4518. }
  4519. pthread_cancel(view_thread);
  4520. CALCULATOR->terminateThreads();
  4521. }
  4522. void KQalculate::angleUnitDegrees() {
  4523. kpAngleGroup->blockSignals(true);
  4524. evalops.parse_options.angle_unit = ANGLE_UNIT_DEGREES;
  4525. expression_format_updated(true);
  4526. kpAngleGroup->setButton(0);
  4527. kpAngleGroup->blockSignals(false);
  4528. }
  4529. void KQalculate::angleUnitRadians() {
  4530. kpAngleGroup->blockSignals(true);
  4531. evalops.parse_options.angle_unit = ANGLE_UNIT_RADIANS;
  4532. expression_format_updated(true);
  4533. kpAngleGroup->setButton(1);
  4534. kpAngleGroup->blockSignals(false);
  4535. }
  4536. void KQalculate::angleUnitGradians() {
  4537. kpAngleGroup->blockSignals(true);
  4538. evalops.parse_options.angle_unit = ANGLE_UNIT_GRADIANS;
  4539. expression_format_updated(true);
  4540. kpAngleGroup->setButton(2);
  4541. kpAngleGroup->blockSignals(false);
  4542. }
  4543. void KQalculate::angleUnitNone() {
  4544. kpAngleGroup->blockSignals(true);
  4545. evalops.parse_options.angle_unit = ANGLE_UNIT_NONE;
  4546. expression_format_updated(true);
  4547. kpAngleGroup->setButton(3);
  4548. kpAngleGroup->blockSignals(false);
  4549. }
  4550. void KQalculate::placeUnitsSeparately(bool b) {
  4551. printops.place_units_separately = b;
  4552. result_format_updated();
  4553. }
  4554. void KQalculate::enableDenominatorPrefixes(bool b) {
  4555. printops.use_denominator_prefix = b;
  4556. result_format_updated();
  4557. }
  4558. void KQalculate::enableUseOfAllPrefixes(bool b) {
  4559. printops.use_all_prefixes = b;
  4560. result_format_updated();
  4561. }
  4562. void KQalculate::enablePrefixes(bool b) {
  4563. printops.use_unit_prefixes = b;
  4564. result_format_updated();
  4565. }
  4566. void KQalculate::autoNoConversion() {
  4567. evalops.auto_post_conversion = POST_CONVERSION_NONE;
  4568. expression_calculation_updated();
  4569. }
  4570. void KQalculate::autoConvertToBaseUnits() {
  4571. evalops.auto_post_conversion = POST_CONVERSION_BASE;
  4572. expression_calculation_updated();
  4573. }
  4574. void KQalculate::autoConvertToBestUnit() {
  4575. evalops.auto_post_conversion = POST_CONVERSION_BEST;
  4576. expression_calculation_updated();
  4577. }
  4578. void KQalculate::allowInfiniteResult(bool b) {
  4579. evalops.allow_infinite = b;
  4580. expression_calculation_updated();
  4581. }
  4582. void KQalculate::allowComplexResult(bool b) {
  4583. evalops.allow_complex = b;
  4584. expression_calculation_updated();
  4585. }
  4586. void KQalculate::calculateVariables(bool b) {
  4587. evalops.calculate_variables = b;
  4588. expression_calculation_updated();
  4589. }
  4590. void KQalculate::enableUnknowns(bool b) {
  4591. evalops.parse_options.unknowns_enabled = b;
  4592. expression_format_updated(b);
  4593. }
  4594. void KQalculate::enableUnits(bool b) {
  4595. evalops.parse_options.units_enabled = b;
  4596. expression_format_updated(b);
  4597. }
  4598. void KQalculate::enableFunctions(bool b) {
  4599. evalops.parse_options.functions_enabled = b;
  4600. expression_format_updated(b);
  4601. }
  4602. void KQalculate::enableVariables(bool b) {
  4603. evalops.parse_options.variables_enabled = b;
  4604. expression_format_updated(b);
  4605. }
  4606. void KQalculate::updateExchangeRates() {
  4607. if(fetch_exchange_rates(15)) {
  4608. CALCULATOR->loadExchangeRates();
  4609. }
  4610. expression_calculation_updated();
  4611. }
  4612. void KQalculate::insertRaise() {
  4613. if(rpn_mode) {
  4614. calculateRPN(OPERATION_RAISE);
  4615. return;
  4616. }
  4617. if(!evalops.parse_options.rpn) {
  4618. expressionEdit->wrapSelection();
  4619. expressionEdit->deselect();
  4620. }
  4621. insert_text("^");
  4622. }
  4623. void KQalculate::insertLn() {
  4624. insertButtonFunction(CALCULATOR->f_ln);
  4625. }
  4626. void KQalculate::insertLog() {
  4627. MathFunction *f = CALCULATOR->getActiveFunction("log10");
  4628. if(f) {
  4629. insertButtonFunction(f);
  4630. } else {
  4631. KMessageBox::error(this, i18n("log10 function not found."));
  4632. }
  4633. }
  4634. void KQalculate::insertSqrt() {
  4635. insertButtonFunction(CALCULATOR->f_sqrt);
  4636. }
  4637. void KQalculate::insertTan() {
  4638. if(kpHyp->isOn()) {
  4639. if(kpInv->isOn()) {
  4640. insertButtonFunction(CALCULATOR->f_atanh);
  4641. } else {
  4642. insertButtonFunction(CALCULATOR->f_tanh);
  4643. }
  4644. } else {
  4645. if(kpInv->isOn()) {
  4646. insertButtonFunction(CALCULATOR->f_atan);
  4647. } else {
  4648. insertButtonFunction(CALCULATOR->f_tan);
  4649. }
  4650. }
  4651. }
  4652. void KQalculate::insertSin() {
  4653. if(kpHyp->isOn()) {
  4654. kpHyp->setOn(false);
  4655. if(kpInv->isOn()) {
  4656. kpInv->setOn(false);
  4657. insertButtonFunction(CALCULATOR->f_asinh);
  4658. } else {
  4659. insertButtonFunction(CALCULATOR->f_sinh);
  4660. }
  4661. } else {
  4662. if(kpInv->isOn()) {
  4663. kpInv->setOn(false);
  4664. insertButtonFunction(CALCULATOR->f_asin);
  4665. } else {
  4666. insertButtonFunction(CALCULATOR->f_sin);
  4667. }
  4668. }
  4669. }
  4670. void KQalculate::insertCos() {
  4671. if(kpHyp->isOn()) {
  4672. kpHyp->setOn(false);
  4673. if(kpInv->isOn()) {
  4674. kpInv->setOn(false);
  4675. insertButtonFunction(CALCULATOR->f_acosh);
  4676. } else {
  4677. insertButtonFunction(CALCULATOR->f_cosh);
  4678. }
  4679. } else {
  4680. if(kpInv->isOn()) {
  4681. kpInv->setOn(false);
  4682. insertButtonFunction(CALCULATOR->f_acos);
  4683. } else {
  4684. insertButtonFunction(CALCULATOR->f_cos);
  4685. }
  4686. }
  4687. }
  4688. void KQalculate::insertDivision() {
  4689. if(rpn_mode) {
  4690. calculateRPN(OPERATION_DIVIDE);
  4691. return;
  4692. }
  4693. if(!evalops.parse_options.rpn) {
  4694. expressionEdit->wrapSelection();
  4695. expressionEdit->deselect();
  4696. }
  4697. if(printops.use_unicode_signs && printops.division_sign == DIVISION_SIGN_DIVISION && can_display_unicode_string_function(SIGN_DIVISION, (void*) expressionEdit)) {
  4698. insert_text(SIGN_DIVISION);
  4699. } else {
  4700. insert_text("/");
  4701. }
  4702. }
  4703. void KQalculate::insertTimes() {
  4704. if(rpn_mode) {
  4705. calculateRPN(OPERATION_MULTIPLY);
  4706. return;
  4707. }
  4708. if(!evalops.parse_options.rpn) {
  4709. expressionEdit->wrapSelection();
  4710. expressionEdit->deselect();
  4711. }
  4712. if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_DOT && can_display_unicode_string_function(SIGN_MULTIDOT, (void*) expressionEdit)) {
  4713. insert_text(SIGN_MULTIDOT);
  4714. } else if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_DOT && can_display_unicode_string_function(SIGN_SMALLCIRCLE, (void*) expressionEdit)) {
  4715. insert_text(SIGN_SMALLCIRCLE);
  4716. } else if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_X && can_display_unicode_string_function(SIGN_MULTIPLICATION, (void*) expressionEdit)) {
  4717. insert_text(SIGN_MULTIPLICATION);
  4718. } else {
  4719. insert_text("*");
  4720. }
  4721. }
  4722. void KQalculate::calculateRPN(int op) {
  4723. if(expression_has_changed && !expressionEdit->text().stripWhiteSpace().isEmpty()) {
  4724. execute();
  4725. }
  4726. execute_expression_force = true;
  4727. execute_expression_do_stack = false;
  4728. execute_expression_do_mathoperation = true;
  4729. execute_expression_op = (MathOperation) op;
  4730. execute_expression_f = NULL;
  4731. execute_expression2();
  4732. }
  4733. void KQalculate::calculateRPN(MathFunction *f) {
  4734. if(expression_has_changed && !expressionEdit->text().stripWhiteSpace().isEmpty()) {
  4735. execute();
  4736. }
  4737. execute_expression_force = true;
  4738. execute_expression_do_stack = false;
  4739. execute_expression_do_mathoperation = true;
  4740. execute_expression_f = f;
  4741. execute_expression2();
  4742. }
  4743. void KQalculate::RPNStackEnter(Variable *v) {
  4744. CALCULATOR->RPNStackEnter(new MathStructure(v), true);
  4745. mstruct->unref();
  4746. mstruct = CALCULATOR->getRPNRegister(1);
  4747. mstruct->ref();
  4748. RPNRegisterAdded(v->preferredDisplayName(printops.abbreviate_names, printops.use_unicode_signs, false, printops.use_reference_names, printops.can_display_unicode_string_function, (void*) stackList).name.c_str());
  4749. }
  4750. void KQalculate::RPNRegisterAdded(const QString &text, size_t index) {
  4751. if(index == 0) {
  4752. new KListViewItem(stackList, QString::number(index + 1), text);
  4753. } else {
  4754. new KListViewItem(stackList, getRPNRegister(index - 1), QString::number(index + 1), text);
  4755. }
  4756. updateRPNIndexes();
  4757. clearStackButton->setEnabled(true);
  4758. }
  4759. void KQalculate::RPNRegisterRemoved(size_t index) {
  4760. delete getRPNRegister(index);
  4761. updateRPNIndexes();
  4762. if(CALCULATOR->RPNStackSize() == 0) {
  4763. clearStackButton->setEnabled(false);
  4764. }
  4765. }
  4766. void KQalculate::RPNRegisterChanged(const QString &text, size_t index) {
  4767. getRPNRegister(index)->setText(1, text);
  4768. }
  4769. QListViewItem *KQalculate::getRPNRegister(size_t index) {
  4770. QListViewItem *li = stackList->firstChild();
  4771. while(li) {
  4772. if(index == 0) return li;
  4773. index--;
  4774. li = li->nextSibling();
  4775. }
  4776. return NULL;
  4777. }
  4778. void KQalculate::clearStack() {
  4779. CALCULATOR->clearRPNStack();
  4780. stackList->clear();
  4781. clearresult();
  4782. mstruct->clear();
  4783. clearStackButton->setEnabled(false);
  4784. }
  4785. void KQalculate::registerUp() {
  4786. QListViewItem *li = stackList->selectedItem();
  4787. if(li) {
  4788. size_t index = (size_t) li->text(0).toUInt() - 1;
  4789. if(index == 0) return;
  4790. CALCULATOR->moveRPNRegisterUp(index + 1);
  4791. QListViewItem *li2 = li->itemAbove();
  4792. QString str = li2->text(1);
  4793. li2->setText(1, li->text(1));
  4794. li->setText(1, str);
  4795. stackList->setSelected(li2, true);
  4796. if(index == 1) {
  4797. mstruct->unref();
  4798. mstruct = CALCULATOR->getRPNRegister(1);
  4799. mstruct->ref();
  4800. setResult(NULL, true, false, false, "", 0, true);
  4801. }
  4802. }
  4803. }
  4804. void KQalculate::registerDown() {
  4805. QListViewItem *li = stackList->selectedItem();
  4806. if(li) {
  4807. size_t index = (size_t) li->text(0).toUInt() - 1;
  4808. if(index + 1 == CALCULATOR->RPNStackSize()) return;
  4809. CALCULATOR->moveRPNRegisterDown(index + 1);
  4810. QListViewItem *li2 = li->nextSibling();
  4811. QString str = li2->text(1);
  4812. li2->setText(1, li->text(1));
  4813. li->setText(1, str);
  4814. stackList->setSelected(li2, true);
  4815. if(index == 0) {
  4816. mstruct->unref();
  4817. mstruct = CALCULATOR->getRPNRegister(1);
  4818. mstruct->ref();
  4819. setResult(NULL, true, false, false, "", 0, true);
  4820. }
  4821. }
  4822. }
  4823. void KQalculate::deleteRegister() {
  4824. QListViewItem *li = stackList->selectedItem();
  4825. if(li) {
  4826. size_t index = (size_t) li->text(0).toUInt() - 1;
  4827. CALCULATOR->deleteRPNRegister(index + 1);
  4828. delete li;
  4829. if(CALCULATOR->RPNStackSize() == 0) {
  4830. clearresult();
  4831. mstruct->clear();
  4832. clearStackButton->setEnabled(false);
  4833. } else if(index == 0) {
  4834. mstruct->unref();
  4835. mstruct = CALCULATOR->getRPNRegister(1);
  4836. mstruct->ref();
  4837. setResult(NULL, true, false, false, "", 0, true);
  4838. }
  4839. updateRPNIndexes();
  4840. }
  4841. }
  4842. void KQalculate::editRegister() {
  4843. QListViewItem *li = stackList->selectedItem();
  4844. if(!li) return;
  4845. stackList->rename(li, 1);
  4846. }
  4847. void KQalculate::updateRPNIndexes() {
  4848. QListViewItem *li = stackList->firstChild();
  4849. size_t i = 1;
  4850. while(li) {
  4851. li->setText(0, QString::number(i));
  4852. i++;
  4853. li = li->nextSibling();
  4854. }
  4855. }
  4856. void KQalculate::stackRegisterMoved() {
  4857. QListViewItem *li = stackList->firstChild();
  4858. size_t i = 0;
  4859. size_t old_index;
  4860. while(li) {
  4861. old_index = (size_t) li->text(0).toUInt() - 1;
  4862. if(old_index != i) {
  4863. CALCULATOR->moveRPNRegister(old_index + 1, i + 1);
  4864. if(i == 0) {
  4865. mstruct->unref();
  4866. mstruct = CALCULATOR->getRPNRegister(1);
  4867. mstruct->ref();
  4868. setResult(NULL, true, false, false, "", 0, true);
  4869. }
  4870. updateRPNIndexes();
  4871. registerSelected();
  4872. return;
  4873. }
  4874. i++;
  4875. li = li->nextSibling();
  4876. }
  4877. }
  4878. void KQalculate::stackRegisterSet(QListViewItem *li) {
  4879. execute_expression_stack_index = (size_t) li->text(0).toUInt() - 1;
  4880. execute_expression_force = true;
  4881. execute_expression_do_stack = true;
  4882. execute_expression_do_mathoperation = false;
  4883. execute_expression2();
  4884. }
  4885. void KQalculate::popupStackMenu(KListView*, QListViewItem *li, const QPoint &p) {
  4886. stackMenu->setItemEnabled(stackMenu->idAt(0), li != NULL);
  4887. stackMenu->setItemEnabled(stackMenu->idAt(1), li != NULL);
  4888. stackMenu->setItemEnabled(stackMenu->idAt(3), CALCULATOR->RPNStackSize() > 0);
  4889. stackMenu->popup(p);
  4890. }
  4891. void KQalculate::registerSelected() {
  4892. QListViewItem *li = stackList->selectedItem();
  4893. if(li) {
  4894. size_t index = (size_t) li->text(0).toUInt() - 1;
  4895. registerUpButton->setEnabled(index != 0);
  4896. registerDownButton->setEnabled(index + 1 < CALCULATOR->RPNStackSize());
  4897. editRegisterButton->setEnabled(true);
  4898. deleteRegisterButton->setEnabled(true);
  4899. } else {
  4900. registerUpButton->setEnabled(false);
  4901. registerDownButton->setEnabled(false);
  4902. editRegisterButton->setEnabled(false);
  4903. deleteRegisterButton->setEnabled(false);
  4904. }
  4905. }
  4906. void KQalculate::insertPlus() {
  4907. if(rpn_mode) {
  4908. calculateRPN(OPERATION_ADD);
  4909. return;
  4910. }
  4911. if(!evalops.parse_options.rpn) {
  4912. expressionEdit->wrapSelection();
  4913. expressionEdit->deselect();
  4914. }
  4915. insert_text("+");
  4916. }
  4917. void KQalculate::insertMinus() {
  4918. if(rpn_mode) {
  4919. calculateRPN(OPERATION_SUBTRACT);
  4920. return;
  4921. }
  4922. if(!evalops.parse_options.rpn) {
  4923. expressionEdit->wrapSelection();
  4924. expressionEdit->deselect();
  4925. }
  4926. if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_MINUS, (void*) expressionEdit)) insert_text(SIGN_MINUS);
  4927. else insert_text("-");
  4928. }
  4929. void KQalculate::insertAns() {
  4930. insert_text(vans[0]->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str());
  4931. }
  4932. void KQalculate::insertExp() {
  4933. if(rpn_mode) {
  4934. calculateRPN(OPERATION_EXP10);
  4935. return;
  4936. }
  4937. if(printops.lower_case_e) insert_text("e");
  4938. else insert_text("E");
  4939. }
  4940. void KQalculate::insertDot() {
  4941. insert_text(CALCULATOR->getDecimalPoint().c_str());
  4942. }
  4943. void KQalculate::insertKP0() {
  4944. insert_text("0");
  4945. }
  4946. void KQalculate::insertKP9() {
  4947. insert_text("9");
  4948. }
  4949. void KQalculate::insertKP8() {
  4950. insert_text("8");
  4951. }
  4952. void KQalculate::insertKP7() {
  4953. insert_text("7");
  4954. }
  4955. void KQalculate::insertKP6() {
  4956. insert_text("6");
  4957. }
  4958. void KQalculate::insertKP5() {
  4959. insert_text("5");
  4960. }
  4961. void KQalculate::insertKP4() {
  4962. insert_text("4");
  4963. }
  4964. void KQalculate::insertKP3() {
  4965. insert_text("3");
  4966. }
  4967. void KQalculate::insertKP2() {
  4968. insert_text("2");
  4969. }
  4970. void KQalculate::insertKP1() {
  4971. insert_text("1");
  4972. }
  4973. void KQalculate::expressionDel() {
  4974. expressionEdit->del();
  4975. }
  4976. void KQalculate::clearExpression() {
  4977. expressionEdit->clear();
  4978. }
  4979. void KQalculate::insertSquare() {
  4980. if(rpn_mode) {
  4981. calculateRPN(CALCULATOR->f_sq);
  4982. return;
  4983. }
  4984. if(evalops.parse_options.rpn) {
  4985. insertButtonFunction(CALCULATOR->f_sq);
  4986. } else {
  4987. expressionEdit->wrapSelection();
  4988. expressionEdit->deselect();
  4989. insert_text("^2");
  4990. }
  4991. }
  4992. void KQalculate::setFractionMode(bool b) {
  4993. if(b) {
  4994. ActionFractionalDisplayFraction->activate();
  4995. } else {
  4996. ActionFractionalDisplayDecimal->activate();
  4997. }
  4998. }
  4999. void KQalculate::setExactMode(bool b) {
  5000. if(b) {
  5001. ActionApproximationAlwaysExact->activate();
  5002. } else {
  5003. ActionApproximationTryExact->activate();
  5004. }
  5005. }
  5006. void KQalculate::kpSetAngleUnit(int index) {
  5007. switch(index) {
  5008. case 0: {
  5009. ActionAngleUnitDegrees->activate();
  5010. break;
  5011. }
  5012. case 1: {
  5013. ActionAngleUnitRadians->activate();
  5014. break;
  5015. }
  5016. case 2: {
  5017. ActionAngleUnitGradians->activate();
  5018. break;
  5019. }
  5020. case 3: {
  5021. ActionAngleUnitNone->activate();
  5022. break;
  5023. }
  5024. }
  5025. }
  5026. void KQalculate::kpSetNumericalMode(int index) {
  5027. switch(index) {
  5028. case 0: {
  5029. printops.negative_exponents = false;
  5030. printops.sort_options.minus_last = true;
  5031. ActionNumericalDisplayNormal->activate();
  5032. break;
  5033. }
  5034. case 1: {
  5035. ActionNumericalDisplayEngineering->activate();
  5036. break;
  5037. }
  5038. case 2: {
  5039. printops.negative_exponents = true;
  5040. printops.sort_options.minus_last = false;
  5041. ActionNumericalDisplayScientific->activate();
  5042. break;
  5043. }
  5044. case 3: {
  5045. printops.negative_exponents = true;
  5046. printops.sort_options.minus_last = false;
  5047. ActionNumericalDisplayPurelyScientific->activate();
  5048. break;
  5049. }
  5050. case 4: {
  5051. printops.negative_exponents = false;
  5052. printops.sort_options.minus_last = true;
  5053. ActionNumericalDisplaySimple->activate();
  5054. break;
  5055. }
  5056. }
  5057. ActionNegativeExponents->setChecked(printops.negative_exponents);
  5058. ActionSortMinusLast->setChecked(printops.sort_options.minus_last);
  5059. }
  5060. void KQalculate::kpSetBaseSelected(int index) {
  5061. switch(index) {
  5062. case 7: {
  5063. numberBaseOther();
  5064. break;
  5065. }
  5066. }
  5067. }
  5068. void KQalculate::kpSetBase(int index) {
  5069. switch(index) {
  5070. case 0: {
  5071. ActionNumberBaseBinary->activate();
  5072. break;
  5073. }
  5074. case 1: {
  5075. ActionNumberBaseOctal->activate();
  5076. break;
  5077. }
  5078. case 2: {
  5079. ActionNumberBaseDecimal->activate();
  5080. break;
  5081. }
  5082. case 3: {
  5083. ActionNumberBaseHexadecimal->activate();
  5084. break;
  5085. }
  5086. case 4: {
  5087. ActionNumberBaseSexagesimal->activate();
  5088. break;
  5089. }
  5090. case 5: {
  5091. ActionNumberBaseTimeFormat->activate();
  5092. break;
  5093. }
  5094. case 6: {
  5095. ActionNumberBaseRomanNumerals->activate();
  5096. break;
  5097. }
  5098. case 7: {
  5099. ActionNumberBaseOther->activate();
  5100. break;
  5101. }
  5102. }
  5103. }
  5104. void KQalculate::insertMod() {
  5105. insertButtonFunction(CALCULATOR->f_mod);
  5106. }
  5107. void KQalculate::insertFactorial() {
  5108. if(rpn_mode) {
  5109. insertButtonFunction(CALCULATOR->f_factorial);
  5110. return;
  5111. }
  5112. expressionEdit->wrapSelection();
  5113. expressionEdit->deselect();
  5114. insert_text("!");
  5115. }
  5116. void KQalculate::storeResult() {
  5117. if(!store_dialog) {
  5118. store_dialog = new QalculateEditVariableDialog(this);
  5119. }
  5120. Variable *v = store_dialog->editVariable(i18n("Temporary"), NULL, mstruct, true);
  5121. if(v) {
  5122. update_vmenu();
  5123. variable_inserted(v);
  5124. }
  5125. }
  5126. void KQalculate::manageVariables() {
  5127. if(!variables_dialog) {
  5128. variables_dialog = new QalculateVariablesDialog();
  5129. variables_dialog->updateVariableTree();
  5130. QObject::connect(variables_dialog, SIGNAL(variablesChanged()), this, SLOT(update_vmenu()));
  5131. QObject::connect(variables_dialog, SIGNAL(insertRequest(Variable*)), this, SLOT(insertVariable(Variable*)));
  5132. }
  5133. variables_dialog->show();
  5134. }
  5135. void KQalculate::insertVariable(Variable *v) {
  5136. insert_text(v->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str());
  5137. variable_inserted(v);
  5138. }
  5139. void KQalculate::insertFunction(MathFunction *f, QWidget *parent) {
  5140. if(!CALCULATOR->stillHasFunction(f)) {
  5141. KMessageBox::error(parent, i18n("Function does not exist anymore."));
  5142. update_fmenu();
  5143. return;
  5144. }
  5145. if(f->args() == 0) {
  5146. QString str = f->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str();
  5147. str += "()";
  5148. insert_text(str);
  5149. function_inserted(f);
  5150. } else {
  5151. QalculateInsertFunctionDialog *dialog = new QalculateInsertFunctionDialog(f, parent, expressionEdit->selectedText());
  5152. int rcode = dialog->exec();
  5153. if(rcode != QDialog::Rejected) {
  5154. if(rcode == QDialog::Accepted) {
  5155. insert_text(dialog->functionExpression());
  5156. } else {
  5157. expressionEdit->setText(dialog->functionExpression());
  5158. execute();
  5159. expressionEdit->setFocus();
  5160. }
  5161. function_inserted(f);
  5162. }
  5163. delete dialog;
  5164. }
  5165. }
  5166. void KQalculate::applyFunction(MathFunction *f, QWidget *parent) {
  5167. if(!CALCULATOR->stillHasFunction(f)) {
  5168. KMessageBox::error(parent, i18n("Function does not exist anymore."));
  5169. update_fmenu();
  5170. return;
  5171. }
  5172. if(rpn_mode) {
  5173. calculateRPN(f);
  5174. return;
  5175. }
  5176. QString str = f->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str();
  5177. if(f->args() == 0) {
  5178. str += "()";
  5179. } else {
  5180. str += "(";
  5181. str += vans[0]->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str();
  5182. str += ")";
  5183. }
  5184. insert_text(str);
  5185. function_inserted(f);
  5186. execute();
  5187. }
  5188. void KQalculate::convertToUnitConvertToDialogExpression() {
  5189. error_timer->stop();
  5190. mstruct->set(CALCULATOR->convert(*mstruct, convert_to_unit_expression_dialog->unitExpressionEdit->text().ascii(), evalops));
  5191. result_action_executed();
  5192. error_timer->start(100);
  5193. }
  5194. void KQalculate::convertToUnitExpression() {
  5195. if(!convert_to_unit_expression_dialog) {
  5196. convert_to_unit_expression_dialog = new QalculateConvertUnitsDialog(this);
  5197. convert_to_unit_expression_dialog->updateUnitTree();
  5198. QObject::connect(convert_to_unit_expression_dialog, SIGNAL(applyClicked()), this, SLOT(convertToUnitConvertToDialogExpression()));
  5199. QObject::connect(convert_to_unit_expression_dialog, SIGNAL(okClicked()), this, SLOT(convertToUnitConvertToDialogExpression()));
  5200. QObject::connect(convert_to_unit_expression_dialog, SIGNAL(unitsChanged()), this, SLOT(update_umenus()));
  5201. }
  5202. convert_to_unit_expression_dialog->show();
  5203. }
  5204. void KQalculate::convertNumberBases() {
  5205. if(!convert_number_bases_dialog) {
  5206. convert_number_bases_dialog = new QalculateConvertNumberBasesDialog();
  5207. }
  5208. convert_number_bases_dialog->show();
  5209. }
  5210. void KQalculate::insertManagedFunction(MathFunction *f) {
  5211. insertFunction(f, functions_dialog);
  5212. }
  5213. void KQalculate::applyManagedFunction(MathFunction *f) {
  5214. applyFunction(f, functions_dialog);
  5215. }
  5216. void KQalculate::manageFunctions() {
  5217. if(!functions_dialog) {
  5218. functions_dialog = new QalculateFunctionsDialog();
  5219. functions_dialog->updateFunctionTree();
  5220. QObject::connect(functions_dialog, SIGNAL(functionsChanged()), this, SLOT(update_fmenu()));
  5221. QObject::connect(functions_dialog, SIGNAL(insertRequest(MathFunction*)), this, SLOT(insertManagedFunction(MathFunction*)));
  5222. QObject::connect(functions_dialog, SIGNAL(applyRequest(MathFunction*)), this, SLOT(applyManagedFunction(MathFunction*)));
  5223. }
  5224. functions_dialog->show();
  5225. }
  5226. void KQalculate::newUnit() {
  5227. if(!unit_edit_dialog) {
  5228. unit_edit_dialog = new QalculateEditUnitDialog(this);
  5229. }
  5230. Unit *u = unit_edit_dialog->editUnit();
  5231. if(u) {
  5232. update_umenus();
  5233. unit_inserted(u);
  5234. }
  5235. }
  5236. void KQalculate::newDataSet() {
  5237. if(!dataset_edit_dialog) {
  5238. dataset_edit_dialog = new QalculateEditDataSetDialog(this);
  5239. }
  5240. MathFunction *f = dataset_edit_dialog->editDataSet();
  5241. if(f) {
  5242. update_fmenu();
  5243. function_inserted(f);
  5244. }
  5245. }
  5246. void KQalculate::newFunction() {
  5247. if(!function_edit_dialog) {
  5248. function_edit_dialog = new QalculateEditFunctionDialog(this);
  5249. }
  5250. MathFunction *f = function_edit_dialog->editFunction();
  5251. if(f) {
  5252. update_fmenu();
  5253. function_inserted(f);
  5254. }
  5255. }
  5256. void KQalculate::newUnknownVariable() {
  5257. if(!unknown_edit_dialog) {
  5258. unknown_edit_dialog = new QalculateEditUnknownVariableDialog(this);
  5259. }
  5260. Variable *v = unknown_edit_dialog->editVariable(i18n("My Variables"));
  5261. if(v) {
  5262. update_vmenu();
  5263. variable_inserted(v);
  5264. }
  5265. }
  5266. void KQalculate::newVector() {
  5267. if(!matrix_edit_dialog) {
  5268. matrix_edit_dialog = new QalculateEditMatrixVectorDialog(this);
  5269. }
  5270. Variable *v = matrix_edit_dialog->newVector(i18n("Vectors"));
  5271. if(v) {
  5272. update_vmenu();
  5273. variable_inserted(v);
  5274. }
  5275. }
  5276. void KQalculate::newMatrix() {
  5277. if(!matrix_edit_dialog) {
  5278. matrix_edit_dialog = new QalculateEditMatrixVectorDialog(this);
  5279. }
  5280. Variable *v = matrix_edit_dialog->newMatrix(i18n("Matrices"));
  5281. if(v) {
  5282. update_vmenu();
  5283. variable_inserted(v);
  5284. }
  5285. }
  5286. void KQalculate::newVariable() {
  5287. if(!variable_edit_dialog) {
  5288. variable_edit_dialog = new QalculateEditVariableDialog(false);
  5289. }
  5290. Variable *v = variable_edit_dialog->editVariable(i18n("My Variables"));
  5291. if(v) {
  5292. update_vmenu();
  5293. variable_inserted(v);
  5294. }
  5295. }
  5296. void KQalculate::exportCSVFile() {
  5297. if(!export_csv_dialog) {
  5298. export_csv_dialog = new QalculateExportCSVDialog(this);
  5299. }
  5300. export_csv_dialog->exportCSVFile();
  5301. }
  5302. void KQalculate::importCSVFile() {
  5303. if(!import_csv_dialog) {
  5304. import_csv_dialog = new QalculateImportCSVDialog(this);
  5305. }
  5306. if(import_csv_dialog->importCSVFile()) {
  5307. update_vmenu();
  5308. }
  5309. }
  5310. void KQalculate::saveAsImage() {
  5311. QString filename;
  5312. while(true) {
  5313. filename = KFileDialog::getSaveFileName("qalculate.png", "image/png", this, i18n("Save Image"));
  5314. if(filename.isEmpty()) {
  5315. return;
  5316. } else {
  5317. if(QFile::exists(filename)) {
  5318. if(KMessageBox::warningContinueCancel(this, i18n("A file named \"%1\" already exists. Are you sure you want to overwrite it?" ).arg(filename), i18n("Overwrite File?"), i18n( "&Overwrite" )) != KMessageBox::Cancel) {
  5319. break;
  5320. }
  5321. } else {
  5322. break;
  5323. }
  5324. }
  5325. }
  5326. QString str = result_text;
  5327. str.replace("width=1 ", "");
  5328. QSimpleRichText text(str, resultLabel->font());
  5329. QPicture picture;
  5330. QPainter p(&picture);
  5331. text.setWidth(1000);
  5332. text.draw(&p, 0, 0, QRect(), QColorGroup(Qt::black, Qt::white, Qt::white, Qt::white, Qt::white, Qt::black, Qt::white));
  5333. p.flush();
  5334. p.end();
  5335. QPixmap pixmap(picture.boundingRect().width(), picture.boundingRect().height());
  5336. pixmap.fill(Qt::white);
  5337. QPainter p2(&pixmap);
  5338. p2.drawPicture(-picture.boundingRect().x(), -picture.boundingRect().y(), picture);
  5339. p2.flush();
  5340. p2.end();
  5341. QImage image(pixmap.convertToImage());
  5342. image.setAlphaBuffer(true);
  5343. int h = image.height(), w = image.width();
  5344. QRgb pixel;
  5345. for(int r =0; r < h; r++) {
  5346. for(int c =0; c < w; c++) {
  5347. pixel = image.pixel(c, r);
  5348. image.setPixel(c, r, qRgba(0, 0, 0, 0xff - ((qRed(pixel) + qBlue(pixel) + qGreen(pixel))/ 3)));
  5349. }
  5350. }
  5351. if(!image.save(filename, "PNG")) {
  5352. KMessageBox::error(this, i18n("Failed to save image."));
  5353. }
  5354. }
  5355. void KQalculate::saveDefinitions() {
  5356. save_defs();
  5357. }
  5358. void KQalculate::plotFunctionsData() {
  5359. if(!plot_dialog) {
  5360. plot_dialog = new QalculatePlotDialog();
  5361. }
  5362. plot_dialog->expressionEdit->setText(expressionEdit->text());
  5363. plot_dialog->show();
  5364. }
  5365. void KQalculate::periodicTable() {
  5366. if(!periodic_table_dialog) {
  5367. periodic_table_dialog = new QalculatePeriodicTableDialog();
  5368. }
  5369. periodic_table_dialog->show();
  5370. }
  5371. void KQalculate::onSetPrefixMenuItemActivated(int id) {
  5372. if(!menu_set_prefix_ids.contains(id)) return;
  5373. result_prefix_changed(menu_set_prefix_ids[id]);
  5374. }
  5375. void KQalculate::onConvertToUnitMenuItemActivated(int id) {
  5376. if(!menu_to_unit_ids.contains(id)) return;
  5377. error_timer->stop();
  5378. mstruct->set(CALCULATOR->convert(*mstruct, menu_to_unit_ids[id], evalops));
  5379. result_action_executed();
  5380. error_timer->start(100);
  5381. }
  5382. void KQalculate::preferences() {
  5383. if(!preferences_dialog) {
  5384. preferences_dialog = new QalculatePreferencesDialog(this);
  5385. }
  5386. close_to_systray_was = close_to_systray;
  5387. display_expression_status_was = display_expression_status;
  5388. preferences_dialog->editPreferences();
  5389. }
  5390. void KQalculate::applyPreferences() {
  5391. if(use_custom_result_font) {
  5392. QFont font(resultLabel->font());
  5393. font.fromString(custom_result_font);
  5394. resultLabel->setFont(font);
  5395. } else {
  5396. resultLabel->unsetFont();
  5397. }
  5398. if(use_custom_expression_font) {
  5399. QFont font(expressionEdit->font());
  5400. font.fromString(custom_expression_font);
  5401. expressionEdit->setFont(font);
  5402. } else {
  5403. expressionEdit->unsetFont();
  5404. }
  5405. updateStatusLabelFonts();
  5406. set_unicode_buttons();
  5407. result_display_updated();
  5408. if(close_to_systray != close_to_systray_was) {
  5409. showSystemTrayIcon(close_to_systray);
  5410. }
  5411. if(display_expression_status != display_expression_status_was) {
  5412. if(display_expression_status) {
  5413. statusLabel_l->show();
  5414. } else {
  5415. statusLabel_l->hide();
  5416. }
  5417. }
  5418. displayParseStatus();
  5419. bool use_button_pixmaps = false;
  5420. if(use_icon_buttons > 0) {
  5421. use_button_pixmaps = true;
  5422. } else if(use_icon_buttons < 0) {
  5423. KConfig config("kdeglobals", true, false);
  5424. config.setGroup("KDE");
  5425. use_button_pixmaps = config.readBoolEntry("ShowIconsOnPushButtons", false);
  5426. }
  5427. if(leftButtonsSeparator->isVisible() == use_button_pixmaps) {
  5428. if(use_button_pixmaps) {
  5429. leftButtonsLayout->setSpacing(3);
  5430. executeButton->setText("");
  5431. executeButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("exec", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
  5432. storeButton->setText("");
  5433. storeButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("filesaveas", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
  5434. convertButton->setText("");
  5435. convertButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("qalculate_convert", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
  5436. leftButtonsSeparator->hide();
  5437. stackPageButtonsLayout->setSpacing(3);
  5438. registerUpButton->setText("");
  5439. registerUpButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("up", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
  5440. registerDownButton->setText("");
  5441. registerDownButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("down", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
  5442. editRegisterButton->setText("");
  5443. editRegisterButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("edit", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
  5444. deleteRegisterButton->setText("");
  5445. deleteRegisterButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("editdelete", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
  5446. clearStackButton->setText("");
  5447. clearStackButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("view_remove", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
  5448. } else {
  5449. leftButtonsLayout->setSpacing(6);
  5450. if(rpn_mode) executeButton->setText(i18n("Enter"));
  5451. else executeButton->setText(i18n("="));
  5452. executeButton->setIconSet(QIconSet());
  5453. storeButton->setText(i18n("Store"));
  5454. storeButton->setIconSet(QIconSet());
  5455. convertButton->setText(i18n("Convert"));
  5456. convertButton->setIconSet(QIconSet());
  5457. leftButtonsSeparator->show();
  5458. stackPageButtonsLayout->setSpacing(6);
  5459. registerUpButton->setText(i18n("Up"));
  5460. registerUpButton->setIconSet(QIconSet());
  5461. registerDownButton->setText(i18n("Down"));
  5462. registerDownButton->setIconSet(QIconSet());
  5463. editRegisterButton->setText(i18n("Edit"));
  5464. editRegisterButton->setIconSet(QIconSet());
  5465. deleteRegisterButton->setText(i18n("Delete"));
  5466. deleteRegisterButton->setIconSet(QIconSet());
  5467. clearStackButton->setText(i18n("Clear"));
  5468. clearStackButton->setIconSet(QIconSet());
  5469. }
  5470. updateButtonWidths();
  5471. }
  5472. }
  5473. void KQalculate::copyResult() {
  5474. QApplication::clipboard()->setText(result_history_text, QClipboard::Clipboard);
  5475. }
  5476. void KQalculate::clearHistory() {
  5477. historyBrowser->setText("&nbsp;");
  5478. expressionEdit->setFocus();
  5479. inhistory.clear();
  5480. inhistory_type.clear();
  5481. inhistory_current_id = 0;
  5482. inhistory_id.clear();
  5483. initial_inhistory_index = 0;
  5484. initial_result_index = 0;
  5485. }
  5486. void KQalculate::convertToBestUnit() {
  5487. error_timer->stop();
  5488. mstruct->set(CALCULATOR->convertToBestUnit(*mstruct, evalops));
  5489. result_action_executed();
  5490. error_timer->start(100);
  5491. }
  5492. void KQalculate::convertToBaseUnits() {
  5493. error_timer->stop();
  5494. mstruct->set(CALCULATOR->convertToBaseUnits(*mstruct, evalops));
  5495. result_action_executed();
  5496. error_timer->start(100);
  5497. }
  5498. void KQalculate::applySetUnknowns(bool okclicked) {
  5499. QString str;
  5500. QString result_mod = "";
  5501. bool b = false;
  5502. mstruct->set(*mstruct_before_unknowns);
  5503. for(size_t i = 1; i <= unknowns_mstruct->size(); i++) {
  5504. str = unknowns_entries[i - 1]->text().stripWhiteSpace();
  5505. if(unknown_changed[i - 1] || !str.isEmpty()) {
  5506. if(!result_mod.isEmpty()) {
  5507. result_mod += CALCULATOR->getComma().c_str();
  5508. result_mod += " ";
  5509. }
  5510. result_mod += unknowns_mstruct->getChild(i)->print().c_str();
  5511. result_mod += "=";
  5512. if(str.isEmpty()) {
  5513. result_mod += "?";
  5514. } else {
  5515. result_mod += str;
  5516. mstruct->replace(*unknowns_mstruct->getChild(i), CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), evalops));
  5517. b = true;
  5518. unknown_changed[i - 1] = true;
  5519. }
  5520. }
  5521. }
  5522. if(b) {
  5523. b_unknowns_changed = true;
  5524. if(okclicked && !rpn_mode) {
  5525. MathStructure mp(*mstruct);
  5526. printops.can_display_unicode_string_arg = historyBrowser;
  5527. mp.format(printops);
  5528. str = mp.print(printops).c_str();
  5529. expressionEdit->blockSignals(true);
  5530. expressionEdit->setText(str);
  5531. printops.can_display_unicode_string_arg = NULL;
  5532. //expressionEdit->addToHistory(str);
  5533. expressionEdit->expression_history_index = -1;
  5534. expressionEdit->blockSignals(false);
  5535. expressionEdit->setFocus();
  5536. expressionEdit->selectAll();
  5537. expression_has_changed2 = true;
  5538. displayParseStatus();
  5539. }
  5540. mstruct->eval(evalops);
  5541. }
  5542. if(b_unknowns_changed) {
  5543. printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
  5544. setResult(NULL, true, false, false, result_mod);
  5545. }
  5546. //if(!okclicked && b) mstruct->set(*mstruct_before_unknowns);
  5547. }
  5548. void KQalculate::setUnknownsApplyClicked() {
  5549. applySetUnknowns(false);
  5550. }
  5551. void KQalculate::setUnknowns() {
  5552. if(expression_has_changed && !rpn_mode) execute_expression(true);
  5553. unknowns_mstruct = new MathStructure();
  5554. mstruct->findAllUnknowns(*unknowns_mstruct);
  5555. if(unknowns_mstruct->size() == 0) {
  5556. KMessageBox::error(this, i18n("No unknowns in result."));
  5557. return;
  5558. }
  5559. KDialogBase *dialog = new KDialogBase(this, 0, true, i18n("Set Unknowns"));
  5560. QObject::connect(dialog, SIGNAL(applyClicked()), this, SLOT(setUnknownsApplyClicked()));
  5561. QGrid *grid = dialog->makeGridMainWidget(2, Qt::Horizontal);
  5562. unknowns_entries.clear();
  5563. for(size_t i = 1; i <= unknowns_mstruct->size(); i++) {
  5564. new QLabel(unknowns_mstruct->getChild(i)->print().c_str(), grid);
  5565. unknowns_entries.push_back(new KLineEdit(grid));
  5566. if(i == 1) unknowns_entries[0]->setFocus();
  5567. }
  5568. mstruct_before_unknowns = new MathStructure(*mstruct);
  5569. b_unknowns_changed = false;
  5570. unknown_changed.clear();
  5571. unknown_changed.resize(unknowns_mstruct->size(), false);
  5572. int response = dialog->exec();
  5573. if(response == QDialog::Accepted) {
  5574. applySetUnknowns(true);
  5575. } else {
  5576. if(b_unknowns_changed) {
  5577. QString result_mod = "";
  5578. for(size_t i = 1; i <= unknowns_mstruct->size(); i++) {
  5579. if(unknown_changed[i - 1]) {
  5580. if(!result_mod.isEmpty()) {
  5581. result_mod += CALCULATOR->getComma().c_str();
  5582. result_mod += " ";
  5583. }
  5584. result_mod += unknowns_mstruct->getChild(i)->print().c_str();
  5585. result_mod += "=";
  5586. result_mod += "?";
  5587. }
  5588. }
  5589. mstruct->set(*mstruct_before_unknowns);
  5590. printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
  5591. setResult(NULL, true, false, false, result_mod);
  5592. expressionEdit->setFocus();
  5593. }
  5594. }
  5595. delete dialog;
  5596. delete mstruct_before_unknowns;
  5597. delete unknowns_mstruct;
  5598. }
  5599. void KQalculate::manageDataSets() {
  5600. if(!datasets_dialog) {
  5601. datasets_dialog = new QalculateDataSetsDialog();
  5602. datasets_dialog->updateDataSetTree();
  5603. QObject::connect(datasets_dialog, SIGNAL(dataSetsChanged()), this, SLOT(update_fmenu()));
  5604. }
  5605. datasets_dialog->show();
  5606. }
  5607. void KQalculate::factorize() {
  5608. executeCommand(COMMAND_FACTORIZE);
  5609. }
  5610. void KQalculate::simplify() {
  5611. executeCommand(COMMAND_SIMPLIFY);
  5612. }
  5613. void KQalculate::manageUnits() {
  5614. if(!units_dialog) {
  5615. units_dialog = new QalculateUnitsDialog();
  5616. units_dialog->updateUnitTree();
  5617. QObject::connect(units_dialog, SIGNAL(unitsChanged()), this, SLOT(update_umenus()));
  5618. QObject::connect(units_dialog, SIGNAL(insertRequest(Unit*)), this, SLOT(insertUnit(Unit*)));
  5619. QObject::connect(units_dialog, SIGNAL(convertRequest(Unit*)), this, SLOT(convertResult(Unit*)));
  5620. }
  5621. units_dialog->show();
  5622. }
  5623. void KQalculate::insertUnit(Unit *u) {
  5624. if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) {
  5625. insert_text(((CompositeUnit*) u)->print(true, printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) expressionEdit).c_str());
  5626. } else {
  5627. insert_text(u->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, true, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str());
  5628. }
  5629. unit_inserted(u);
  5630. }
  5631. void KQalculate::convertResult(Unit *u) {
  5632. error_timer->stop();
  5633. mstruct->set(CALCULATOR->convert(*mstruct, u, evalops));
  5634. result_action_executed();
  5635. error_timer->start(100);
  5636. }
  5637. void KQalculate::insertMatrixVector(const MathStructure *m, bool do_vector, bool is_text_struct, bool is_result) {
  5638. if(!insert_matrix_dialog) {
  5639. insert_matrix_dialog = new QalculateInsertMatrixVectorDialog(this);
  5640. }
  5641. QString str = insert_matrix_dialog->editMatrixVector(m, do_vector, is_text_struct, is_result);
  5642. if(!str.isEmpty()) {
  5643. insert_text(str);
  5644. }
  5645. }
  5646. void KQalculate::insertMatrix() {
  5647. QString str = expressionEdit->selectedText().stripWhiteSpace();
  5648. if(!str.isEmpty()) {
  5649. MathStructure mstruct_sel;
  5650. CALCULATOR->beginTemporaryStopMessages();
  5651. CALCULATOR->parse(&mstruct_sel, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), evalops.parse_options);
  5652. CALCULATOR->endTemporaryStopMessages();
  5653. if(mstruct_sel.isMatrix()) {
  5654. insertMatrixVector(&mstruct_sel, false);
  5655. return;
  5656. }
  5657. }
  5658. insertMatrixVector(NULL, false);
  5659. }
  5660. void KQalculate::insertVector() {
  5661. QString str = expressionEdit->selectedText().stripWhiteSpace();
  5662. if(!str.isEmpty()) {
  5663. MathStructure mstruct_sel;
  5664. CALCULATOR->beginTemporaryStopMessages();
  5665. CALCULATOR->parse(&mstruct_sel, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), evalops.parse_options);
  5666. CALCULATOR->endTemporaryStopMessages();
  5667. if(mstruct_sel.isVector() && !mstruct_sel.isMatrix()) {
  5668. insertMatrixVector(&mstruct_sel, true);
  5669. return;
  5670. }
  5671. }
  5672. insertMatrixVector(NULL, true);
  5673. }
  5674. void KQalculate::keyPressEvent(QKeyEvent *e) {
  5675. KMainWindow::keyPressEvent(e);
  5676. if(e->isAccepted()) return;
  5677. if(close_to_systray && e->key() == Key_Escape && e->state() == 0) {
  5678. e->accept();
  5679. hide();
  5680. return;
  5681. }
  5682. if(!expressionEdit->hasFocus() && e->key() != Qt::Key_Control && e->key() != Qt::Key_Meta && e->key() != Qt::Key_Shift && e->key() != Qt::Key_Alt) {
  5683. expressionEdit->setFocus();
  5684. expressionEdit->keyPressEvent(e);
  5685. }
  5686. }
  5687. bool KQalculate::queryClose() {
  5688. if(m_parent->sessionSaving() || !close_to_systray) return true;
  5689. hide();
  5690. setShown(false);
  5691. return false;
  5692. }
  5693. void KQalculate::saveProperties(KConfig*) {
  5694. KConfig *cfg = KGlobal::config();
  5695. cfg->setGroup("Session");
  5696. cfg->writeEntry("docked", isHidden());
  5697. }
  5698. void KQalculate::readProperties(KConfig*) {
  5699. KConfig *cfg = KGlobal::config();
  5700. cfg->setGroup("Session");
  5701. if(close_to_systray && cfg->readBoolEntry("docked", true)) {
  5702. hide();
  5703. } else {
  5704. show();
  5705. }
  5706. }
  5707. void KQalculate::display_function_hint(MathFunction *f, int arg_index) {
  5708. if(!f) return;
  5709. int iargs = f->maxargs();
  5710. Argument *arg;
  5711. Argument default_arg;
  5712. QString str, str2, str3;
  5713. const ExpressionName *ename = &f->preferredName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) statusLabel_l);
  5714. bool last_is_vctr = f->getArgumentDefinition(iargs) && f->getArgumentDefinition(iargs)->type() == ARGUMENT_TYPE_VECTOR;
  5715. if(arg_index > iargs && iargs >= 0 && !last_is_vctr) {
  5716. statusLabel_l->setText(i18n("Too many arguments for %1().").arg(ename->name.c_str()), false, false, true);
  5717. return;
  5718. }
  5719. str += ename->name.c_str();
  5720. if(iargs < 0) {
  5721. iargs = f->minargs() + 1;
  5722. if(arg_index > iargs) arg_index = iargs;
  5723. }
  5724. if(arg_index > iargs && last_is_vctr) arg_index = iargs;
  5725. str += "(";
  5726. int i_reduced = 0;
  5727. if(iargs != 0) {
  5728. for(int i2 = 1; i2 <= iargs; i2++) {
  5729. if(i2 > f->minargs() && arg_index < i2) {
  5730. str += "[";
  5731. }
  5732. if(i2 > 1) {
  5733. str += CALCULATOR->getComma().c_str();
  5734. str += " ";
  5735. }
  5736. if(i2 == arg_index) str += "<b>";
  5737. arg = f->getArgumentDefinition(i2);
  5738. if(arg && !arg->name().empty()) {
  5739. str2 = arg->name().c_str();
  5740. } else {
  5741. str2 = i18n("argument");
  5742. str2 += " ";
  5743. str2 += QString::number(i2);
  5744. }
  5745. if(i2 == arg_index) {
  5746. if(arg) {
  5747. if(i_reduced == 2) str3 = arg->print().c_str();
  5748. else str3 = arg->printlong().c_str();
  5749. } else {
  5750. Argument arg_default;
  5751. if(i_reduced == 2) str3 = arg_default.print().c_str();
  5752. else str3 = arg_default.printlong().c_str();
  5753. }
  5754. if(!str3.isEmpty()) {
  5755. str2 += ": ";
  5756. str2 += str3;
  5757. }
  5758. str2.replace("&", "&amp;");
  5759. str2.replace(">", "&gt;");
  5760. str2.replace("<", "&lt;");
  5761. str += str2;
  5762. str += "</b>";
  5763. if(i_reduced < 2) {
  5764. QSimpleRichText qsrt(str, statusLabel_l->font());
  5765. qsrt.setWidth(statusLabel_l->contentsRect().width() + 100);
  5766. if(qsrt.widthUsed() > statusLabel_l->contentsRect().width() - 4) {
  5767. str = ename->name.c_str();
  5768. str += "(";
  5769. if(i2 != 1) {
  5770. str += "...";
  5771. i_reduced++;
  5772. } else {
  5773. i_reduced = 2;
  5774. }
  5775. i2--;
  5776. }
  5777. } else {
  5778. i_reduced = 0;
  5779. }
  5780. } else {
  5781. str2.replace("&", "&amp;");
  5782. str2.replace(">", "&gt;");
  5783. str2.replace("<", "&lt;");
  5784. str += str2;
  5785. if(i2 > f->minargs() && arg_index < i2) {
  5786. str += "]";
  5787. }
  5788. }
  5789. }
  5790. if(f->maxargs() < 0) {
  5791. str += CALCULATOR->getComma().c_str();
  5792. str += " ...";
  5793. }
  5794. }
  5795. str += ")";
  5796. statusLabel_l->setText(str, false, false, false);
  5797. }
  5798. void KQalculate::displayParseStatus() {
  5799. if(!display_expression_status) return;
  5800. if(expressionEdit->text().length() == 0) {
  5801. statusLabel_l->setText("", true, false, false);
  5802. parsed_expression = "";
  5803. expression_has_changed2 = false;
  5804. had_errors_before = false;
  5805. had_warnings_before = false;
  5806. return;
  5807. }
  5808. MathStructure mparse, mfunc;
  5809. string str_e, str_u;
  5810. int pos = expressionEdit->cursorPosition();
  5811. bool full_parsed = false;
  5812. bool had_errors = false, had_warnings = false;
  5813. evalops.parse_options.preserve_format = true;
  5814. if(pos > 0) {
  5815. evalops.parse_options.unended_function = &mfunc;
  5816. CALCULATOR->beginTemporaryStopMessages();
  5817. if(pos < (int) expressionEdit->text().length()) {
  5818. QString str = expressionEdit->text();
  5819. str.truncate(pos);
  5820. str_e = CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options);
  5821. if(!CALCULATOR->separateToExpression(str_e, str_u, evalops)) {
  5822. CALCULATOR->parse(&mparse, str_e, evalops.parse_options);
  5823. }
  5824. } else {
  5825. str_e = CALCULATOR->unlocalizeExpression(expressionEdit->text().ascii(), evalops.parse_options);
  5826. CALCULATOR->separateToExpression(str_e, str_u, evalops);
  5827. CALCULATOR->parse(&mparse, str_e, evalops.parse_options);
  5828. full_parsed = true;
  5829. }
  5830. int warnings_count;
  5831. had_errors = CALCULATOR->endTemporaryStopMessages(NULL, &warnings_count) > 0;
  5832. had_warnings = warnings_count > 0;
  5833. evalops.parse_options.unended_function = NULL;
  5834. }
  5835. if(mfunc.isFunction()) {
  5836. if(mfunc.countChildren() == 0) {
  5837. display_function_hint(mfunc.function(), 1);
  5838. } else {
  5839. display_function_hint(mfunc.function(), mfunc.countChildren());
  5840. }
  5841. }
  5842. if(expression_has_changed2) {
  5843. if(!full_parsed) {
  5844. CALCULATOR->beginTemporaryStopMessages();
  5845. str_e = CALCULATOR->unlocalizeExpression(expressionEdit->text().ascii(), evalops.parse_options);
  5846. CALCULATOR->separateToExpression(str_e, str_u, evalops);
  5847. CALCULATOR->parse(&mparse, str_e, evalops.parse_options);
  5848. int warnings_count;
  5849. had_errors = CALCULATOR->endTemporaryStopMessages(NULL, &warnings_count) > 0;
  5850. had_warnings = warnings_count > 0;
  5851. }
  5852. PrintOptions po;
  5853. po.preserve_format = true;
  5854. po.show_ending_zeroes = true;
  5855. po.lower_case_e = printops.lower_case_e;
  5856. po.lower_case_numbers = printops.lower_case_numbers;
  5857. po.base_display = printops.base_display;
  5858. po.abbreviate_names = false;
  5859. po.hide_underscore_spaces = true;
  5860. po.use_unicode_signs = printops.use_unicode_signs;
  5861. po.multiplication_sign = printops.multiplication_sign;
  5862. po.division_sign = printops.division_sign;
  5863. po.short_multiplication = false;
  5864. po.excessive_parenthesis = true;
  5865. po.improve_division_multipliers = false;
  5866. po.can_display_unicode_string_function = &can_display_unicode_string_function;
  5867. po.can_display_unicode_string_arg = (void*) statusLabel_l;
  5868. po.spell_out_logical_operators = printops.spell_out_logical_operators;
  5869. po.restrict_to_parent_precision = false;
  5870. mparse.format(po);
  5871. parsed_expression = mparse.print(po).c_str();
  5872. if(!str_u.empty()) {
  5873. parsed_expression += CALCULATOR->localToString().c_str();
  5874. CALCULATOR->beginTemporaryStopMessages();
  5875. CompositeUnit cu("", "temporary_composite_parse", "", str_u);
  5876. int warnings_count;
  5877. had_errors = CALCULATOR->endTemporaryStopMessages(NULL, &warnings_count) > 0 || had_errors;
  5878. had_warnings = had_warnings || warnings_count > 0;
  5879. mparse = cu.generateMathStructure(!printops.negative_exponents);
  5880. mparse.format(po);
  5881. parsed_expression += mparse.print(po).c_str();
  5882. }
  5883. parsed_expression.replace("&", "&amp;");
  5884. parsed_expression.replace(">", "&gt;");
  5885. parsed_expression.replace("<", "&lt;");
  5886. if(!mfunc.isFunction()) statusLabel_l->setText(parsed_expression, true, had_errors, had_warnings);
  5887. expression_has_changed2 = false;
  5888. had_errors_before = had_errors;
  5889. had_warnings_before = had_warnings;
  5890. } else if(!mfunc.isFunction()) {
  5891. statusLabel_l->setText(parsed_expression, true, had_errors_before, had_warnings_before);
  5892. }
  5893. evalops.parse_options.preserve_format = false;
  5894. }
  5895. void KQalculate::editHistoryExpression() {
  5896. if(current_history_index < inhistory.size()) {
  5897. QString text = inhistory[current_history_index];
  5898. text.replace("&amp;", "&");
  5899. text.replace("&gt;", ">");
  5900. text.replace("&lt;", "<");
  5901. text.replace("<br>", " ");
  5902. expressionEdit->setText(text);
  5903. expressionEdit->setFocus();
  5904. }
  5905. }
  5906. void KQalculate::editHistoryParse() {
  5907. if(current_history_index < inhistory.size()) {
  5908. QString text = inhistory[current_history_index];
  5909. text.replace("&amp;", "&");
  5910. text.replace("&gt;", ">");
  5911. text.replace("&lt;", "<");
  5912. text.replace("<br>", " ");
  5913. expressionEdit->setText(text);
  5914. expressionEdit->setFocus();
  5915. }
  5916. }
  5917. void KQalculate::editHistoryResult() {
  5918. if(current_history_index < inhistory.size()) {
  5919. QString text = inhistory[current_history_index];
  5920. text.replace("&amp;", "&");
  5921. text.replace("&gt;", ">");
  5922. text.replace("&lt;", "<");
  5923. text.replace("<br>", " ");
  5924. expressionEdit->setText(text);
  5925. expressionEdit->setFocus();
  5926. }
  5927. }
  5928. void KQalculate::insertHistoryResultVariable() {
  5929. if(current_history_index < inhistory.size()) {
  5930. int id = inhistory_id[current_history_index];
  5931. for(size_t i = 0; i < 5; i++) {
  5932. if(vans_id_start[i] != -1 && id >= vans_id_start[i] && (vans_id_end[i] == -1 || id <= vans_id_end[i])) {
  5933. insertVariable(vans[i]);
  5934. }
  5935. }
  5936. }
  5937. }
  5938. QalculateHistoryBrowser::QalculateHistoryBrowser(QWidget *parent, const char *name) : KTextBrowser(parent, name) {}
  5939. QalculateHistoryBrowser::~QalculateHistoryBrowser() {}
  5940. QPopupMenu *QalculateHistoryBrowser::createPopupMenu(const QPoint &pos) {
  5941. QPopupMenu *menu = KTextBrowser::createPopupMenu(pos);
  5942. menu->insertSeparator();
  5943. mainWin->ActionClearHistory->plug(menu);
  5944. QString name = anchorAt(pos, Qt::AnchorName);
  5945. if(!name.isEmpty()) {
  5946. int id = name.toInt();
  5947. QValueVector<int>::size_type i = 0;
  5948. for(; i < inhistory_id.size(); i++) {
  5949. if(inhistory_id[i] == id) {
  5950. break;
  5951. }
  5952. }
  5953. mainWin->current_history_index = i;
  5954. if(i < inhistory_id.size()) {
  5955. switch(inhistory_type[i]) {
  5956. case QALCULATE_HISTORY_PARSE: {}
  5957. case QALCULATE_HISTORY_PARSE_APPROXIMATE: {
  5958. menu->insertItem(i18n("Edit Expression"), mainWin, SLOT(editHistoryParse()));
  5959. break;
  5960. }
  5961. case QALCULATE_HISTORY_EXPRESSION: {
  5962. menu->insertItem(i18n("Edit Expression"), mainWin, SLOT(editHistoryExpression()));
  5963. break;
  5964. }
  5965. case QALCULATE_HISTORY_RESULT_APPROXIMATE: {}
  5966. case QALCULATE_HISTORY_RESULT: {
  5967. menu->insertItem(i18n("Edit Result"), mainWin, SLOT(editHistoryResult()));
  5968. for(size_t i = 0; i < 5; i++) {
  5969. if(vans_id_start[i] != -1 && id >= vans_id_start[i] && (vans_id_end[i] == -1 || id <= vans_id_end[i])) {
  5970. menu->insertItem(i18n("Insert Result Variable"), mainWin, SLOT(insertHistoryResultVariable()));
  5971. break;
  5972. }
  5973. }
  5974. break;
  5975. }
  5976. default: {}
  5977. }
  5978. }
  5979. }
  5980. return menu;
  5981. }
  5982. QalculateParseLabel::QalculateParseLabel(QWidget *parent, const char *name) : QLabel(parent, name) {
  5983. QLabel::setText("<b>A</b>");
  5984. bb = false;
  5985. ec = false;
  5986. wc = false;
  5987. }
  5988. QalculateParseLabel::~QalculateParseLabel() {}
  5989. void QalculateParseLabel::setText(QString text, bool break_begin, bool error_color, bool warning_color) {
  5990. bb = break_begin;
  5991. ec = error_color;
  5992. wc = warning_color;
  5993. parsetext = "<nobr>";
  5994. parsetext += text;
  5995. parsetext += "</nobr>";
  5996. update();
  5997. }
  5998. void QalculateParseLabel::drawContents(QPainter *p) {
  5999. QColorGroup cg = colorGroup();
  6000. if(ec) {
  6001. cg.setColor(QColorGroup::Text, status_error_color);
  6002. } else if(wc) {
  6003. cg.setColor(QColorGroup::Text, status_warning_color);
  6004. } else if(backgroundMode() != PaletteBase && isEnabled()) {
  6005. cg.setColor(QColorGroup::Text, paletteForegroundColor());
  6006. }
  6007. QRect cr = contentsRect();
  6008. cr.setX(cr.x() + 4);
  6009. cr.setWidth(cr.width() - 4);
  6010. QSimpleRichText qsrt(parsetext, font());
  6011. qsrt.setWidth(p, cr.width() + 100);
  6012. if(qsrt.widthUsed() > cr.width()) {
  6013. if(bb) {
  6014. QSimpleRichText qsrt_dots("...", font());
  6015. qsrt_dots.draw(p, cr.x(), cr.y(), cr, cg, 0);
  6016. cr.setX(cr.x() + qsrt_dots.widthUsed());
  6017. cr.setWidth(cr.width() - qsrt_dots.widthUsed());
  6018. qsrt.draw(p, cr.x() + cr.width() - qsrt.widthUsed(), cr.y(), cr, cg, 0);
  6019. } else {
  6020. QSimpleRichText qsrt_dots("...", font());
  6021. qsrt_dots.draw(p, cr.x() + cr.width() - qsrt_dots.widthUsed(), cr.y(), cr, cg, 0);
  6022. cr.setWidth(cr.width() - qsrt_dots.widthUsed());
  6023. qsrt.draw(p, cr.x(), cr.y(), cr, cg, 0);
  6024. }
  6025. } else {
  6026. qsrt.draw(p, cr.x(), cr.y(), cr, cg, 0);
  6027. }
  6028. }
  6029. QalculateButton::QalculateButton(QWidget *parent, const char *name) : QPushButton(parent, name) {
  6030. setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
  6031. umtcw = true;
  6032. #if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4
  6033. KAcceleratorManager::setNoAccel(this);
  6034. #endif
  6035. }
  6036. QalculateButton::QalculateButton(const QString &text, QWidget *parent, const char *name) : QPushButton(text, parent, name) {
  6037. setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
  6038. umtcw = true;
  6039. #if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4
  6040. KAcceleratorManager::setNoAccel(this);
  6041. #endif
  6042. }
  6043. QalculateButton::QalculateButton(const QIconSet &icon, const QString &text, QWidget *parent, const char *name) : QPushButton(icon, text, parent, name) {
  6044. setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
  6045. umtcw = true;
  6046. #if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4
  6047. KAcceleratorManager::setNoAccel(this);
  6048. #endif
  6049. }
  6050. QalculateButton::~QalculateButton() {}
  6051. void QalculateButton::setUseMinThreeCharWidth(bool b) {
  6052. umtcw = b;
  6053. }
  6054. void QalculateButton::setMarkup(const QString &str) {
  6055. QColorGroup cg(colorGroup());
  6056. cg.setColor(QColorGroup::Text, paletteForegroundColor());
  6057. QSimpleRichText rtext(str, font());
  6058. QPicture picture;
  6059. QPainter p(&picture);
  6060. rtext.draw(&p, 0, 0, QRect(), cg);
  6061. p.flush();
  6062. p.end();
  6063. QRect r = picture.boundingRect();
  6064. QPixmap pixmap(r.width(), rtext.height());
  6065. pixmap.fill(cg.background());
  6066. QPainter p2(&pixmap);
  6067. p2.drawPicture(-r.x(), 0, picture);
  6068. p2.flush();
  6069. p2.end();
  6070. pixmap.setMask(pixmap.createHeuristicMask());
  6071. setPixmap(pixmap);
  6072. }
  6073. QSize QalculateButton::sizeHint() const {
  6074. constPolish();
  6075. int w = 0, h = 0;
  6076. #ifndef QT_NO_ICONSET
  6077. if(iconSet() && !iconSet()->isNull()) {
  6078. w = iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 10;
  6079. h = iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height() + 10;
  6080. return QSize(w, h).expandedTo(QApplication::globalStrut());
  6081. }
  6082. #endif
  6083. QSize sz;
  6084. if(pixmap()) {
  6085. QPixmap *pm = (QPixmap *)pixmap();
  6086. w = pm->width();
  6087. h = pm->height();
  6088. if(umtcw) {
  6089. QFontMetrics fm = fontMetrics();
  6090. sz = fm.size(ShowPrefix, QString::fromLatin1("XXX"));
  6091. if(w < sz.width()) w = sz.width();
  6092. if(w < sz.height()) w = sz.height();
  6093. }
  6094. sz.setWidth(w);
  6095. sz.setHeight(h);
  6096. w += 12;
  6097. h += 10;
  6098. } else {
  6099. QFontMetrics fm = fontMetrics();
  6100. if(umtcw && (text().isEmpty() || text().length() < 3)) {
  6101. sz = fm.size(ShowPrefix, QString::fromLatin1("XXX"));
  6102. } else {
  6103. sz = fm.size(ShowPrefix, text());
  6104. }
  6105. w = sz.width() + 12;
  6106. h = sz.height() + 10;
  6107. }
  6108. return QSize(w, h).boundedTo(style().sizeFromContents(QStyle::CT_PushButton, this, sz)).expandedTo(QApplication::globalStrut());
  6109. }
  6110. QalculateStyleSheet::QalculateStyleSheet(QObject *parent, const char *name) : QStyleSheet(parent, name) {}
  6111. QalculateStyleSheet::~QalculateStyleSheet() {}
  6112. void QalculateStyleSheet::scaleFont(QFont &font, int logicalSize) const {
  6113. if(logicalSize <= 1) {
  6114. font.setPixelSize(1);
  6115. } else if(logicalSize == 2) {
  6116. logicalSize = 1;
  6117. } else if(logicalSize > 7) {
  6118. logicalSize = 7;
  6119. }
  6120. int baseSize = font.pointSize();
  6121. bool pixel = FALSE;
  6122. if(baseSize == -1){
  6123. baseSize = font.pixelSize();
  6124. pixel = TRUE;
  6125. }
  6126. float factor = baseSize;
  6127. int i;
  6128. int scale_level = logicalSize - 3;
  6129. if(scale_level > 0) {
  6130. i = 0;
  6131. while (i < scale_level) {
  6132. factor *= 1.2;
  6133. ++i;
  6134. }
  6135. } else if(scale_level < 0) {
  6136. i = scale_level;
  6137. while (i < 0) {
  6138. factor /= 1.2;
  6139. ++i;
  6140. }
  6141. }
  6142. if(pixel) font.setPixelSize((int) roundf(factor));
  6143. else font.setPointSizeFloat(factor);
  6144. }
  6145. QalculateRPNStackListView::QalculateRPNStackListView(QWidget *parent, const char *name) : KListView(parent, name) {}
  6146. QalculateRPNStackListView::~QalculateRPNStackListView() {}
  6147. void QalculateRPNStackListView::keyPressEvent(QKeyEvent *e) {
  6148. switch(e->key()) {
  6149. case Key_Prior: {}
  6150. case Key_Next: {}
  6151. case Key_Home: {}
  6152. case Key_End: {}
  6153. case Key_Up: {}
  6154. case Key_Down: {
  6155. KListView::keyPressEvent(e);
  6156. break;
  6157. }
  6158. default: {
  6159. if(e->key() == KGlobalSettings::contextMenuKey()) KListView::keyPressEvent(e);
  6160. else e->ignore();
  6161. }
  6162. }
  6163. }
  6164. #include "kqalculate.moc"