summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSlávek Banko <slavek.banko@axis.cz>2016-04-09 15:59:57 +0200
committerSlávek Banko <slavek.banko@axis.cz>2016-04-09 15:59:57 +0200
commitee0c9d4bc3e25a409b3127be2876079f69719978 (patch)
tree04d895b486c04df1fe2e5dedb7cd5705eff06a9b /src
downloadqalculate-tde-ee0c9d4bc3e25a409b3127be2876079f69719978.tar.gz
qalculate-tde-ee0c9d4bc3e25a409b3127be2876079f69719978.zip
Initial import of qalculate-kde 0.9.7
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am58
-rw-r--r--src/buttonwithindexsignal.cpp31
-rw-r--r--src/buttonwithindexsignal.h39
-rw-r--r--src/hi128-app-qalculate_kde.pngbin0 -> 13323 bytes
-rw-r--r--src/hi16-app-qalculate_kde.pngbin0 -> 664 bytes
-rw-r--r--src/hi22-app-qalculate_kde.pngbin0 -> 960 bytes
-rw-r--r--src/hi32-action-qalculate_convert.pngbin0 -> 1506 bytes
-rw-r--r--src/hi32-app-qalculate_kde.pngbin0 -> 1563 bytes
-rw-r--r--src/hi48-app-qalculate_kde.pngbin0 -> 3874 bytes
-rw-r--r--src/hi64-app-qalculate_kde.pngbin0 -> 5910 bytes
-rw-r--r--src/kqalculate.cpp6676
-rw-r--r--src/kqalculate.h593
-rw-r--r--src/main.cpp306
-rw-r--r--src/preferences.cpp865
-rw-r--r--src/preferences.h42
-rw-r--r--src/qalculate_kde.desktop13
-rw-r--r--src/qalculate_kde_utils.cpp307
-rw-r--r--src/qalculate_kde_utils.h74
-rw-r--r--src/qalculate_kdeui.rc168
-rw-r--r--src/qalculatebuttonwithdata.cpp37
-rw-r--r--src/qalculatebuttonwithdata.h48
-rw-r--r--src/qalculateconvertnumberbasesdialog.cpp122
-rw-r--r--src/qalculateconvertnumberbasesdialog.h53
-rw-r--r--src/qalculateconvertunitsdialog.cpp205
-rw-r--r--src/qalculateconvertunitsdialog.h67
-rw-r--r--src/qalculatedatasetsdialog.cpp506
-rw-r--r--src/qalculatedatasetsdialog.h85
-rw-r--r--src/qalculatedecimalsdialog.cpp55
-rw-r--r--src/qalculatedecimalsdialog.h43
-rw-r--r--src/qalculateeditdataobjectdialog.cpp103
-rw-r--r--src/qalculateeditdataobjectdialog.h44
-rw-r--r--src/qalculateeditdatasetdialog.cpp750
-rw-r--r--src/qalculateeditdatasetdialog.h145
-rw-r--r--src/qalculateeditfunctiondialog.cpp799
-rw-r--r--src/qalculateeditfunctiondialog.h140
-rw-r--r--src/qalculateeditmatrixvectordialog.cpp491
-rw-r--r--src/qalculateeditmatrixvectordialog.h82
-rw-r--r--src/qalculateeditnamesdialog.cpp275
-rw-r--r--src/qalculateeditnamesdialog.h65
-rw-r--r--src/qalculateeditunitdialog.cpp425
-rw-r--r--src/qalculateeditunitdialog.h73
-rw-r--r--src/qalculateeditunknownvariabledialog.cpp308
-rw-r--r--src/qalculateeditunknownvariabledialog.h70
-rw-r--r--src/qalculateeditvariabledialog.cpp304
-rw-r--r--src/qalculateeditvariabledialog.h74
-rw-r--r--src/qalculateexportcsvdialog.cpp186
-rw-r--r--src/qalculateexportcsvdialog.h66
-rw-r--r--src/qalculateexpressionedit.cpp1018
-rw-r--r--src/qalculateexpressionedit.h109
-rw-r--r--src/qalculatefunctionsdialog.cpp537
-rw-r--r--src/qalculatefunctionsdialog.h89
-rw-r--r--src/qalculateimportcsvdialog.cpp216
-rw-r--r--src/qalculateimportcsvdialog.h65
-rw-r--r--src/qalculateinsertfunctiondialog.cpp404
-rw-r--r--src/qalculateinsertfunctiondialog.h56
-rw-r--r--src/qalculateinsertmatrixvectordialog.cpp381
-rw-r--r--src/qalculateinsertmatrixvectordialog.h73
-rw-r--r--src/qalculateperiodictabledialog.cpp276
-rw-r--r--src/qalculateperiodictabledialog.h66
-rw-r--r--src/qalculateplotdialog.cpp789
-rw-r--r--src/qalculateplotdialog.h101
-rw-r--r--src/qalculateprecisiondialog.cpp54
-rw-r--r--src/qalculateprecisiondialog.h43
-rw-r--r--src/qalculatepreferencesdialog.cpp414
-rw-r--r--src/qalculatepreferencesdialog.h57
-rw-r--r--src/qalculateresultdisplay.cpp495
-rw-r--r--src/qalculateresultdisplay.h79
-rw-r--r--src/qalculatesetbasedialog.cpp63
-rw-r--r--src/qalculatesetbasedialog.h45
-rw-r--r--src/qalculateunitsdialog.cpp560
-rw-r--r--src/qalculateunitsdialog.h108
-rw-r--r--src/qalculatevariablesdialog.cpp493
-rw-r--r--src/qalculatevariablesdialog.h92
73 files changed, 21476 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
new file mode 100644
index 0000000..c5991ba
--- /dev/null
+++ b/src/Makefile.am
@@ -0,0 +1,58 @@
+# set the include path for X, qt and KDE
+INCLUDES = $(all_includes)
+
+# these are the headers for your project
+
+
+# let automoc handle all of the meta source files (moc)
+METASOURCES = AUTO
+
+messages: rc.cpp
+ $(EXTRACTRC) `find . -name \*.ui -o -name \*.rc` > rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/qalculate_kde.pot
+
+KDE_ICON = AUTO
+
+#########################################################################
+# APPLICATION SECTION
+#########################################################################
+# this is the program that gets installed. it's name is used for all
+# of the other Makefile.am variables
+bin_PROGRAMS = qalculate-kde
+
+# the application source, library search path, and link libraries
+qalculate_kde_SOURCES = buttonwithindexsignal.cpp kqalculate.cpp \
+ main.cpp preferences.cpp qalculatebuttonwithdata.cpp qalculateconvertnumberbasesdialog.cpp \
+ qalculateconvertunitsdialog.cpp qalculatedatasetsdialog.cpp qalculatedecimalsdialog.cpp qalculateeditdataobjectdialog.cpp \
+ qalculateeditdatasetdialog.cpp qalculateeditfunctiondialog.cpp qalculateeditmatrixvectordialog.cpp qalculateeditnamesdialog.cpp \
+ qalculateeditunitdialog.cpp qalculateeditunknownvariabledialog.cpp qalculateeditvariabledialog.cpp qalculateexportcsvdialog.cpp \
+ qalculateexpressionedit.cpp qalculatefunctionsdialog.cpp qalculateimportcsvdialog.cpp qalculateinsertfunctiondialog.cpp \
+ qalculateinsertmatrixvectordialog.cpp qalculate_kde_utils.cpp qalculateperiodictabledialog.cpp qalculateplotdialog.cpp \
+ qalculateprecisiondialog.cpp qalculatepreferencesdialog.cpp qalculatesetbasedialog.cpp \
+ qalculateunitsdialog.cpp qalculatevariablesdialog.cpp qalculateresultdisplay.cpp
+
+qalculate_kde_LDFLAGS = $(KDE_RPATH) $(all_libraries)
+qalculate_kde_LDADD = $(LIB_KDEUI) $(LIB_KIO)
+
+# this is where the desktop file will go
+shelldesktopdir = $(xdg_appsdir)
+shelldesktop_DATA = qalculate_kde.desktop
+
+# this is where the shell's XML-GUI resource file goes
+shellrcdir = $(kde_datadir)/qalculate_kde
+shellrc_DATA = qalculate_kdeui.rc
+
+
+noinst_HEADERS = preferences.h qalculateinsertfunctiondialog.h qalculateinsertmatrixvectordialog.h \
+ buttonwithindexsignal.h qalculateexpressionedit.h qalculateconvertnumberbasesdialog.h \
+ qalculatebuttonwithdata.h qalculatesetbasedialog.h \
+ qalculatevariablesdialog.h qalculatefunctionsdialog.h qalculateunitsdialog.h \
+ qalculateeditunknownvariabledialog.h qalculatedecimalsdialog.h qalculateconvertunitsdialog.h \
+ qalculateprecisiondialog.h qalculateeditunitdialog.h qalculateeditnamesdialog.h \
+ qalculateeditfunctiondialog.h qalculateplotdialog.h qalculateimportcsvdialog.h \
+ qalculateexportcsvdialog.h qalculatepreferencesdialog.h qalculateeditmatrixvectordialog.h \
+ qalculatedatasetsdialog.h qalculateeditdatasetdialog.h qalculateeditdataobjectdialog.h \
+ qalculateresultdisplay.h
+
+install-exec-local:
+ cd $(DESTDIR)$(bindir) && rm -f qalculate; $(LN_S) qalculate-kde qalculate
diff --git a/src/buttonwithindexsignal.cpp b/src/buttonwithindexsignal.cpp
new file mode 100644
index 0000000..34fe66e
--- /dev/null
+++ b/src/buttonwithindexsignal.cpp
@@ -0,0 +1,31 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "buttonwithindexsignal.h"
+
+ButtonWithIndexSignal::ButtonWithIndexSignal(const QString & text, int index, QWidget *parent, const char *name) : QPushButton(text, parent, name) {
+ i = index;
+ connect(this, SIGNAL(clicked()), this, SLOT(emitClickedWithIndex()));
+}
+ButtonWithIndexSignal::~ButtonWithIndexSignal() {}
+void ButtonWithIndexSignal::emitClickedWithIndex() {
+ emit clickedWithIndex(i);
+}
+
+#include "buttonwithindexsignal.moc"
diff --git a/src/buttonwithindexsignal.h b/src/buttonwithindexsignal.h
new file mode 100644
index 0000000..0c0fcfe
--- /dev/null
+++ b/src/buttonwithindexsignal.h
@@ -0,0 +1,39 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef BUTTONWITHINDEXSIGNAL_H
+#define BUTTONWITHINDEXSIGNAL_H
+
+#include <qpushbutton.h>
+
+class ButtonWithIndexSignal : public QPushButton {
+ Q_OBJECT
+
+public:
+ ButtonWithIndexSignal(const QString & text, int index, QWidget *parent = 0, const char *name = 0);
+ virtual ~ButtonWithIndexSignal();
+ int i;
+public slots:
+ void emitClickedWithIndex();
+signals:
+ void clickedWithIndex(int);
+
+};
+
+#endif
diff --git a/src/hi128-app-qalculate_kde.png b/src/hi128-app-qalculate_kde.png
new file mode 100644
index 0000000..133985c
--- /dev/null
+++ b/src/hi128-app-qalculate_kde.png
Binary files differ
diff --git a/src/hi16-app-qalculate_kde.png b/src/hi16-app-qalculate_kde.png
new file mode 100644
index 0000000..0a46460
--- /dev/null
+++ b/src/hi16-app-qalculate_kde.png
Binary files differ
diff --git a/src/hi22-app-qalculate_kde.png b/src/hi22-app-qalculate_kde.png
new file mode 100644
index 0000000..c3d3fe1
--- /dev/null
+++ b/src/hi22-app-qalculate_kde.png
Binary files differ
diff --git a/src/hi32-action-qalculate_convert.png b/src/hi32-action-qalculate_convert.png
new file mode 100644
index 0000000..e032855
--- /dev/null
+++ b/src/hi32-action-qalculate_convert.png
Binary files differ
diff --git a/src/hi32-app-qalculate_kde.png b/src/hi32-app-qalculate_kde.png
new file mode 100644
index 0000000..8fc50d3
--- /dev/null
+++ b/src/hi32-app-qalculate_kde.png
Binary files differ
diff --git a/src/hi48-app-qalculate_kde.png b/src/hi48-app-qalculate_kde.png
new file mode 100644
index 0000000..fdde4fc
--- /dev/null
+++ b/src/hi48-app-qalculate_kde.png
Binary files differ
diff --git a/src/hi64-app-qalculate_kde.png b/src/hi64-app-qalculate_kde.png
new file mode 100644
index 0000000..0c6adbf
--- /dev/null
+++ b/src/hi64-app-qalculate_kde.png
Binary files differ
diff --git a/src/kqalculate.cpp b/src/kqalculate.cpp
new file mode 100644
index 0000000..ce0ac09
--- /dev/null
+++ b/src/kqalculate.cpp
@@ -0,0 +1,6676 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <kdialog.h>
+#include <klocale.h>
+
+#include "kqalculate.h"
+#include "qalculateinsertfunctiondialog.h"
+#include "qalculate_kde_utils.h"
+#include "preferences.h"
+#include "qalculatepreferencesdialog.h"
+#include "qalculateimportcsvdialog.h"
+#include "qalculateexportcsvdialog.h"
+#include "qalculateexpressionedit.h"
+#include "qalculateprecisiondialog.h"
+#include "qalculatedecimalsdialog.h"
+#include "qalculateeditvariabledialog.h"
+#include "qalculateeditmatrixvectordialog.h"
+#include "qalculateeditunitdialog.h"
+#include "qalculateeditfunctiondialog.h"
+#include "qalculateeditdatasetdialog.h"
+#include "qalculateeditunknownvariabledialog.h"
+#include "qalculatevariablesdialog.h"
+#include "qalculatefunctionsdialog.h"
+#include "qalculateunitsdialog.h"
+#include "qalculatedatasetsdialog.h"
+#include "qalculateconvertunitsdialog.h"
+#include "qalculateconvertnumberbasesdialog.h"
+#include "qalculateperiodictabledialog.h"
+#include "qalculateplotdialog.h"
+#include "qalculatesetbasedialog.h"
+#include "qalculateinsertmatrixvectordialog.h"
+
+#include <kwin.h>
+#include <kglobalsettings.h>
+#include <kuniqueapplication.h>
+#include <kstringhandler.h>
+#include <qtable.h>
+#include <kseparator.h>
+#include <kiconloader.h>
+#include <qframe.h>
+#include <qvariant.h>
+#include <qtooltip.h>
+#include <qwhatsthis.h>
+#include <qclipboard.h>
+#include <qstylesheet.h>
+#include <kcompletion.h>
+#include <klineedit.h>
+#include <qlabel.h>
+#include <kmessagebox.h>
+#include <qpixmap.h>
+#include <qpicture.h>
+#include <qpainter.h>
+#include <qfontmetrics.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <time.h>
+#include <math.h>
+#include <dirent.h>
+#include <pthread.h>
+#include <qsimplerichtext.h>
+#include <qstatusbar.h>
+#include <qwidgetstack.h>
+#include <ktextbrowser.h>
+#include <kpushbutton.h>
+#include "qalculateresultdisplay.h"
+#include <qbitmap.h>
+#include <qscrollview.h>
+#include <qobject.h>
+#include <kapplication.h>
+#include <kaction.h>
+#include <qspinbox.h>
+#include <kprogress.h>
+#include <kpopupmenu.h>
+#include <kmenubar.h>
+#include <qlayout.h>
+#include <qtimer.h>
+#include <kcompletionbox.h>
+#include <qstringlist.h>
+#include <qcombobox.h>
+#include <ksystemtray.h>
+#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR > 1
+#include <kactionclasses.h>
+#endif
+#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4
+#include <kaccelmanager.h>
+#endif
+#include <qbuttongroup.h>
+#include <qvbuttongroup.h>
+#include <qradiobutton.h>
+#include <qgrid.h>
+#include <kfiledialog.h>
+#include <qimage.h>
+#include <kaccel.h>
+#include <kio/netaccess.h>
+#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 2
+#include <kinputdialog.h>
+#endif
+#include <kdeversion.h>
+#include <qstyle.h>
+#include <kglobalaccel.h>
+#include <kkeydialog.h>
+#include <kkeybutton.h>
+#include <kcombobox.h>
+
+MathStructure *mstruct, *matrix_mstruct, *parsed_mstruct, *parsed_tostruct;
+QString result_text, result_history_text, parsed_text;
+QWidget *expressionWidget, *resultWidget, *statusWidget_l;
+QWidget *topWidget;
+KQalculate *mainWin = 0;
+bool prev_result_approx;
+extern bool close_to_systray;
+extern bool display_expression_status;
+extern QColor status_error_color;
+extern QColor status_warning_color;
+extern int use_icon_buttons;
+extern bool enable_expression_completion;
+
+extern QString initial_history;
+extern tree_struct function_cats, unit_cats, variable_cats;
+extern vector<void*> ia_units, ia_variables, ia_functions;
+extern vector<MathFunction*> recent_functions;
+extern vector<Variable*> recent_variables;
+extern vector<Unit*> recent_units;
+vector<MathStructure> result_parts;
+
+KnownVariable *vans[5];
+int vans_id_start[5];
+int vans_id_end[5];
+
+extern PrintOptions printops;
+extern EvaluationOptions evalops;
+extern bool rpn_mode, rpn_keypad_only;
+extern bool save_mode_on_exit, save_defs_on_exit;
+
+extern bool canplot;
+
+extern bool use_custom_result_font, use_custom_expression_font, use_custom_status_font;
+extern QString custom_result_font, custom_expression_font, custom_status_font;
+
+extern QTimer *error_timer;
+
+extern QStringList expression_history;
+
+bool expression_has_changed, expression_has_changed2, had_errors_before, had_warnings_before, block_result_update;
+
+FILE *view_pipe_r, *view_pipe_w, *command_pipe_r, *command_pipe_w;
+pthread_t view_thread, command_thread;
+pthread_attr_t view_thread_attr, command_thread_attr;
+bool b_busy, command_thread_started;
+int saved_divisionline_height = 0;
+uint initial_result_index = 0;
+
+extern bool show_keypad, show_history, show_stack;
+
+extern vector<mode_struct> modes;
+
+extern QValueVector<QString> inhistory;
+extern QValueVector<int> inhistory_type;
+extern QValueVector<int> inhistory_id;
+extern int inhistory_current_id;
+int initial_inhistory_index = 0;
+
+const MathStructure *KQalculate::getResultPart(int i) {
+ if(i < 1 || (size_t) i > result_parts.size()) return NULL;
+ return &result_parts[(size_t) i - 1];
+}
+
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+#include <kiconloader.h>
+#include <kconfig.h>
+QPixmap loadSystrayIcon(const QString &icon) {
+ KConfig *appCfg = kapp->config();
+ KConfigGroupSaver configSaver(appCfg, "System Tray");
+ int iconWidth = appCfg->readNumEntry("systrayIconWidth", 22);
+ return KGlobal::instance()->iconLoader()->loadIcon(icon, KIcon::Panel, iconWidth);
+}
+#endif
+
+#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 3
+#define ICON_SIZE_SMALL_MEDIUM KIcon::SizeSmallMedium
+#else
+#define ICON_SIZE_SMALL_MEDIUM 22
+#endif
+
+ModeObject::ModeObject(int mode) : i_mode(mode) {}
+void ModeObject::loadMode() {
+ mainWin->loadMode(i_mode);
+}
+
+KQalculate::KQalculate(KUniqueApplication *parent, const char* name, WFlags fl) : KMainWindow(0, name, fl) {
+
+ if(!name) setName("kqalculate");
+
+ m_parent = parent;
+
+ vans_id_start[0] = -1;
+ vans_id_end[0] = -1;
+ vans_id_start[1] = -1;
+ vans_id_end[1] = -1;
+ vans_id_start[2] = -1;
+ vans_id_end[2] = -1;
+ vans_id_start[3] = -1;
+ vans_id_end[3] = -1;
+ vans_id_start[4] = -1;
+ vans_id_end[4] = -1;
+
+ QStyleSheet::setDefaultSheet(new QalculateStyleSheet());
+
+ insert_matrix_dialog = NULL;
+ preferences_dialog = NULL;
+ precisionDialog = NULL;
+ decimalsDialog = NULL;
+ variable_edit_dialog = NULL;
+ store_dialog = NULL;
+ matrix_edit_dialog = NULL;
+ import_csv_dialog = NULL;
+ export_csv_dialog = NULL;
+ unit_edit_dialog = NULL;
+ function_edit_dialog = NULL;
+ dataset_edit_dialog = NULL;
+ unknown_edit_dialog = NULL;
+ variables_dialog = NULL;
+ functions_dialog = NULL;
+ units_dialog = NULL;
+ datasets_dialog = NULL;
+ convert_to_unit_expression_dialog = NULL;
+ convert_number_bases_dialog = NULL;
+ periodic_table_dialog = NULL;
+ plot_dialog = NULL;
+ set_base_dialog = NULL;
+
+ prev_result_approx = false;
+ expression_has_changed = false;
+ expression_has_changed2 = false;
+ had_errors_before = false;
+ had_warnings_before = false;
+ block_result_update = false;
+
+ history_height = 0;
+
+ trayicon = NULL;
+ ActionHideSystemTrayIcon = new KAction(i18n("Remove from System Tray"), "hidesystemtrayicon", 0, this, SLOT(hideSystemTrayIcon()), actionCollection(), "hide_system_tray_icon");
+ ActionHide = new KAction(i18n("Hide"), "hide", 0, this, SLOT(hide()), actionCollection(), "hide");
+ showSystemTrayIcon(close_to_systray);
+
+ setCentralWidget(new QWidget(this));
+ QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget(), 11, 6);
+ mainLayout->setResizeMode(QLayout::Minimum);
+
+ QHBoxLayout *topLayout = new QHBoxLayout(0, 0, 6);
+
+ bool use_button_pixmaps = false;
+ if(use_icon_buttons > 0) {
+ use_button_pixmaps = true;
+ } else if(use_icon_buttons < 0) {
+ KConfig config("kdeglobals", true, false);
+ config.setGroup("KDE");
+ use_button_pixmaps = config.readBoolEntry("ShowIconsOnPushButtons", false);
+ }
+
+ if(use_button_pixmaps) leftButtonsLayout = new QVBoxLayout(0, 0, 3);
+ else leftButtonsLayout = new QVBoxLayout(0, 0, 6);
+ if(use_button_pixmaps) executeButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("exec", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", centralWidget());
+ else if(rpn_mode) executeButton = new QalculateButton(i18n("Enter"), centralWidget());
+ else executeButton = new QalculateButton(i18n("="), centralWidget());
+ executeButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
+ if(rpn_mode) QToolTip::add(executeButton, i18n("Calculate expression and add to stack"));
+ else QToolTip::add(executeButton, i18n("Calculate expression"));
+ leftButtonsLayout->addWidget(executeButton);
+ leftButtonsSeparator = new KSeparator(Qt::Horizontal, centralWidget());
+ leftButtonsLayout->addWidget(leftButtonsSeparator);
+ if(use_button_pixmaps) leftButtonsSeparator->hide();
+ if(use_button_pixmaps) storeButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("filesaveas", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", centralWidget());
+ else storeButton = new QalculateButton(i18n("Store"), centralWidget());
+ storeButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
+ QToolTip::add(storeButton, i18n("Store result as variable"));
+ leftButtonsLayout->addWidget(storeButton);
+ if(use_button_pixmaps) convertButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("qalculate_convert", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", centralWidget());
+ else convertButton = new QalculateButton(i18n("Convert"), centralWidget());
+ convertButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
+ QToolTip::add(convertButton, i18n("Convert units in result"));
+ leftButtonsLayout->addWidget(convertButton);
+ leftButtonsLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum));
+
+ QVBoxLayout *expressionLayout = new QVBoxLayout(0, 0, 0);
+ expressionEdit = new QalculateExpressionEdit(true, centralWidget());
+ expressionLayout->addWidget(expressionEdit);
+ expressionEdit->setFocus();
+ expressionEdit->expression_history = expression_history;
+ if(!enable_expression_completion) expressionEdit->disableCompletion();
+ QToolTip::add(expressionEdit, i18n("Enter expression here"));
+ QHBoxLayout *statusLayout = new QHBoxLayout(0, 0, 6);
+ statusLabel_l = new QalculateParseLabel(centralWidget());
+ statusLabel_l->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
+ statusLabel_l->setLineWidth(0);
+ statusLabel_l->setMargin(0);
+ statusLabel_l->setAlignment(int(QLabel::AlignTop | QLabel::AlignLeft));
+ if(!display_expression_status) statusLabel_l->hide();
+ statusLayout->addWidget(statusLabel_l);
+ statusLabel_r = new QLabel(i18n("status"), centralWidget());
+ statusLabel_r->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum, false);
+ statusLabel_r->setLineWidth(0);
+ statusLabel_r->setMargin(0);
+ statusLabel_r->setTextFormat(Qt::RichText);
+ statusLabel_r->setAlignment(int(QLabel::AlignTop | QLabel::AlignRight));
+ statusLayout->addWidget(statusLabel_r);
+ expressionLayout->addLayout(statusLayout);
+ resultLabel = new QalculateResultDisplay(centralWidget());
+ resultLabel->setRightMargin(10);
+ expressionLayout->addWidget(resultLabel);
+
+ topLayout->addLayout(expressionLayout);
+ topLayout->addLayout(leftButtonsLayout);
+ mainLayout->addLayout(topLayout);
+
+ resultLabel->setWordWrap(QTextEdit::WidgetWidth);
+ resultLabel->setMargin(0);
+
+ bottomLine = new KSeparator(Qt::Horizontal, centralWidget());
+ mainLayout->addWidget(bottomLine);
+
+ mainStack = new QWidgetStack(centralWidget());
+ mainStack->setEnabled(true);
+ mainStack->setSizePolicy(QSizePolicy((QSizePolicy::SizeType) 5, (QSizePolicy::SizeType) 7, 0, 0, mainStack->sizePolicy().hasHeightForWidth()));
+
+ keypadPage = new QWidget(mainStack);
+ QVBoxLayout *keypadPageLayout = new QVBoxLayout(keypadPage, 0, 12);
+
+ keypadPageLayout->addWidget(new KSeparator(Qt::Horizontal, keypadPage));
+
+ QHBoxLayout *keypadTopLayout = new QHBoxLayout(0, 0, 6);
+ kpExact = new QalculateButton(i18n("Exact"), keypadPage);
+ QToolTip::add(kpExact, i18n("Toggle exact mode"));
+ kpExact->setToggleButton(true);
+ keypadTopLayout->addWidget(kpExact);
+ kpFraction = new QalculateButton(i18n("Fraction"), keypadPage);
+ QToolTip::add(kpFraction, i18n("Toggle fractional display"));
+ kpFraction->setToggleButton(true);
+ keypadTopLayout->addWidget(kpFraction);
+ kpNumericCombo = new QComboBox(true, keypadPage);
+ QToolTip::add(kpNumericCombo, i18n("Numerical display"));
+ kpNumericCombo->setEditable(false);
+ keypadTopLayout->addWidget(kpNumericCombo);
+ kpNumericCombo->insertItem(i18n("Normal"));
+ kpNumericCombo->insertItem(i18n("Engineering"));
+ kpNumericCombo->insertItem(i18n("Scientific"));
+ kpNumericCombo->insertItem(i18n("Pure"));
+ kpNumericCombo->insertItem(i18n("Simple"));
+ kpBaseCombo = new QComboBox(true, keypadPage);
+ QToolTip::add(kpBaseCombo, i18n("Base in result"));
+ kpBaseCombo->setEditable(false);
+ keypadTopLayout->addWidget(kpBaseCombo);
+ keypadPageLayout->addLayout(keypadTopLayout);
+ kpBaseCombo->insertItem(i18n("Binary"));
+ kpBaseCombo->insertItem(i18n("Octal"));
+ kpBaseCombo->insertItem(i18n("Decimal"));
+ kpBaseCombo->insertItem(i18n("Hexadecimal"));
+ kpBaseCombo->insertItem(i18n("Sexagesimal"));
+ kpBaseCombo->insertItem(i18n("Time Format"));
+ kpBaseCombo->insertItem(i18n("Roman"));
+ kpBaseCombo->insertItem(i18n("Other..."));
+
+ QHBoxLayout *keypadBottomLayout = new QHBoxLayout(0, 0, 24);
+
+ QGridLayout *keypadFunctionsLayout = new QGridLayout(0, 5, 3, 0, 6);
+
+ functionsButton = new QalculateButton(i18n("f(x)"), keypadPage);
+ QFont fb_font(functionsButton->font());
+ fb_font.setItalic(true);
+ functionsButton->setFont(fb_font);
+ QToolTip::add(functionsButton, i18n("Open functions manager"));
+ keypadFunctionsLayout->addWidget(functionsButton, 0, 0);
+ kpSqrt = new QalculateButton(i18n("sqrt"), keypadPage);
+ QToolTip::add(kpSqrt, i18n("Square root"));
+ keypadFunctionsLayout->addWidget(kpSqrt, 1, 0);
+ kpRaise = new QalculateButton(keypadPage);
+ kpRaise->setMarkup(i18n("x<sup>y</sup>"));
+ QToolTip::add(kpRaise, i18n("Raise (Ctrl+*)"));
+ keypadFunctionsLayout->addWidget(kpRaise, 0, 1);
+ kpSquare = new QalculateButton(keypadPage);
+ kpSquare->setMarkup(i18n("x<sup>2</sup>"));
+ QToolTip::add(kpSquare, i18n("Square"));
+ keypadFunctionsLayout->addWidget(kpSquare, 0, 2);
+ kpLog = new QalculateButton(i18n("log"), keypadPage);
+ QToolTip::add(kpLog, i18n("Base-10 logarithm"));
+ keypadFunctionsLayout->addWidget(kpLog, 1, 1);
+ kpLn = new QalculateButton(i18n("ln"), keypadPage);
+ QToolTip::add(kpLn, i18n("Natural logarithm"));
+ keypadFunctionsLayout->addWidget(kpLn, 1, 2);
+ kpFactorial = new QalculateButton(i18n("x!"), keypadPage);
+ QToolTip::add(kpFactorial, i18n("Factorial"));
+ keypadFunctionsLayout->addWidget(kpFactorial, 2, 0);
+ kpCos = new QalculateButton(i18n("cos"), keypadPage);
+ QToolTip::add(kpCos, i18n("Cosine"));
+ keypadFunctionsLayout->addWidget(kpCos, 2, 1);
+ kpTan = new QalculateButton(i18n("tan"), keypadPage);
+ QToolTip::add(kpTan, i18n("Tangent"));
+ keypadFunctionsLayout->addWidget(kpTan, 2, 2);
+ kpHyp = new QalculateButton(i18n("hyp"), keypadPage);
+ QToolTip::add(kpHyp, i18n("Toggle hyperbolic functions"));
+ kpHyp->setToggleButton(true);
+ keypadFunctionsLayout->addWidget(kpHyp, 3, 0);
+ kpInv = new QalculateButton(i18n("inv"), keypadPage);
+ QToolTip::add(kpInv, i18n("Toggle inverse functions"));
+ kpInv->setToggleButton(true);
+ keypadFunctionsLayout->addWidget(kpInv, 3, 1);
+ kpSin = new QalculateButton(i18n("sin"), keypadPage);
+ QToolTip::add(kpSin, i18n("Sine"));
+ keypadFunctionsLayout->addWidget(kpSin, 3, 2);
+ QHBoxLayout *keypadAngleLayout = new QHBoxLayout(0, 0, 6);
+ kpAngleGroup = new QButtonGroup();
+ kpAngleGroup->setExclusive(true);
+ kpDegreesButton = new QRadioButton(i18n("Deg"), keypadPage);
+ QToolTip::add(kpDegreesButton, i18n("Angle Unit: Degrees"));
+ kpAngleGroup->insert(kpDegreesButton, 0);
+ keypadAngleLayout->addWidget(kpDegreesButton);
+ kpRadiansButton = new QRadioButton(i18n("Rad"), keypadPage);
+ QToolTip::add(kpRadiansButton, i18n("Angle Unit: Radians"));
+ kpAngleGroup->insert(kpRadiansButton, 1);
+ keypadAngleLayout->addWidget(kpRadiansButton);
+ kpGradiansButton = new QRadioButton(i18n("Gra"), keypadPage);
+ QToolTip::add(kpGradiansButton, i18n("Angle Unit: Gradians"));
+ kpAngleGroup->insert(kpGradiansButton, 2);
+ keypadAngleLayout->addWidget(kpGradiansButton);
+ kpNoAngleUnitButton = new QRadioButton(i18n("None"), keypadPage);
+ kpAngleGroup->insert(kpNoAngleUnitButton, 3);
+ keypadAngleLayout->addWidget(kpNoAngleUnitButton);
+ kpNoAngleUnitButton->hide();
+ keypadAngleLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ keypadFunctionsLayout->addMultiCellLayout(keypadAngleLayout, 4, 4, 0, 2);
+
+#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4
+ KAcceleratorManager::setNoAccel(kpDegreesButton);
+ KAcceleratorManager::setNoAccel(kpRadiansButton);
+ KAcceleratorManager::setNoAccel(kpGradiansButton);
+ KAcceleratorManager::setNoAccel(kpNoAngleUnitButton);
+#endif
+
+ keypadBottomLayout->addLayout(keypadFunctionsLayout);
+
+ QGridLayout *keypadBasicsLayout = new QGridLayout(0, 1, 1, 0, 6);
+ kp7 = new QalculateButton(i18n("7"), keypadPage);
+ keypadBasicsLayout->addWidget(kp7, 0, 0);
+ kp8 = new QalculateButton(i18n("8"), keypadPage);
+ keypadBasicsLayout->addWidget(kp8, 0, 1);
+ kp9 = new QalculateButton(i18n("9"), keypadPage);
+ keypadBasicsLayout->addWidget(kp9, 0, 2);
+ kp4 = new QalculateButton(i18n("4"), keypadPage);
+ keypadBasicsLayout->addWidget(kp4, 1, 0);
+ kp5 = new QalculateButton(i18n("5"), keypadPage);
+ keypadBasicsLayout->addWidget(kp5, 1, 1);
+ kp6 = new QalculateButton(i18n("6"), keypadPage);
+ keypadBasicsLayout->addWidget(kp6, 1, 2);
+ kp1 = new QalculateButton(i18n("1"), keypadPage);
+ keypadBasicsLayout->addWidget(kp1, 2, 0);
+ kp2 = new QalculateButton(i18n("2"), keypadPage);
+ keypadBasicsLayout->addWidget(kp2, 2, 1);
+ kp3 = new QalculateButton(i18n("3"), keypadPage);
+ keypadBasicsLayout->addWidget(kp3, 2, 2);
+ kp0 = new QalculateButton(i18n("0"), keypadPage);
+ keypadBasicsLayout->addWidget(kp0, 3, 0);
+ kpDot = new QalculateButton(".", keypadPage);
+ QToolTip::add(kpDot, i18n("Decimal point"));
+ keypadBasicsLayout->addWidget(kpDot, 3, 1);
+ kpExp = new QalculateButton(i18n("EXP"), keypadPage);
+ QToolTip::add(kpExp, i18n("10^x (Ctrl+Shift+E)"));
+ keypadBasicsLayout->addWidget(kpExp, 3, 2);
+
+ kpDel = new QalculateButton(i18n("Del"), keypadPage);
+ QToolTip::add(kpDel, i18n("Delete"));
+ keypadBasicsLayout->addWidget(kpDel, 0, 3);
+ kpClear = new QalculateButton(i18n("AC"), keypadPage);
+ QToolTip::add(kpClear, i18n("Clear"));
+ keypadBasicsLayout->addWidget(kpClear, 0, 4);
+ kpTimes = new QalculateButton("*", keypadPage);
+ QToolTip::add(kpTimes, i18n("Multiply"));
+ keypadBasicsLayout->addWidget(kpTimes, 1, 3);
+ kpDivision = new QalculateButton("/", keypadPage);
+ QToolTip::add(kpDivision, i18n("Divide"));
+ keypadBasicsLayout->addWidget(kpDivision, 1, 4);
+ kpPlus = new QalculateButton("+", keypadPage);
+ QToolTip::add(kpPlus, i18n("Add"));
+ keypadBasicsLayout->addWidget(kpPlus, 2, 3);
+ kpMinus = new QalculateButton("-", keypadPage);
+ QToolTip::add(kpMinus, i18n("Subtract"));
+ keypadBasicsLayout->addWidget(kpMinus, 2, 4);
+ kpAns = new QalculateButton(i18n("Ans"), keypadPage);
+ QToolTip::add(kpAns, i18n("Previous result"));
+ keypadBasicsLayout->addWidget(kpAns, 3, 3);
+ if(rpn_mode) kpEquals = new QalculateButton(i18n("Ent"), keypadPage);
+ else kpEquals = new QalculateButton(i18n("="), keypadPage);
+ if(rpn_mode) QToolTip::add(kpEquals, i18n("Calculate expression and add to stack"));
+ else QToolTip::add(kpEquals, i18n("Calculate expression"));
+ keypadBasicsLayout->addWidget(kpEquals, 3, 4);
+ keypadBottomLayout->addLayout(keypadBasicsLayout);
+
+ keypadPageLayout->addLayout(keypadBottomLayout);
+
+ keypadPageLayout->addWidget(new KSeparator(Qt::Horizontal, keypadPage));
+ mainStack->addWidget(keypadPage, 0);
+
+ historyPage = new QWidget(mainStack, "historyPage");
+ QVBoxLayout *historyPageLayout = new QVBoxLayout(historyPage, 0, 0);
+ historyBrowser = new QalculateHistoryBrowser(historyPage, "historyBrowser");
+ historyBrowser->setTextFormat(KTextBrowser::RichText);
+ historyBrowser->setWordWrap(KTextBrowser::NoWrap);
+ historyPageLayout->addWidget(historyBrowser);
+ mainStack->addWidget(historyPage, 1);
+
+ stackPage = new QWidget(mainStack, "stackPage");
+ QHBoxLayout *stackPageLayout = new QHBoxLayout(stackPage, 0, 6);
+ stackList = new QalculateRPNStackListView(stackPage, "stackList");
+ stackList->addColumn(i18n("Index"));
+ stackList->addColumn(i18n("Value"));
+ stackList->setColumnAlignment(0, Qt::AlignCenter);
+ stackList->setColumnAlignment(1, Qt::AlignRight);
+ stackList->setFullWidth(true);
+ stackList->setResizeMode(QListView::LastColumn);
+ stackList->setSelectionMode(QListView::Single);
+ stackList->setAllColumnsShowFocus(true);
+ stackList->setRootIsDecorated(false);
+ stackList->setItemsMovable(true);
+ stackList->setDragEnabled(true);
+ stackList->setAcceptDrops(true);
+ stackList->setSorting(-1);
+ stackList->setItemsRenameable(true);
+ stackList->setRenameable(1, true);
+ stackList->setRenameable(0, false);
+ stackPageLayout->addWidget(stackList);
+ if(use_button_pixmaps) stackPageButtonsLayout = new QVBoxLayout(stackPageLayout, 3);
+ else stackPageButtonsLayout = new QVBoxLayout(stackPageLayout, 6);
+ if(use_button_pixmaps) registerUpButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("up", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage);
+ else registerUpButton = new QalculateButton(i18n("Up"), stackPage);
+ QToolTip::add(registerUpButton, i18n("Move selected register up"));
+ registerUpButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
+ stackPageButtonsLayout->addWidget(registerUpButton);
+ if(use_button_pixmaps) registerDownButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("down", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage);
+ else registerDownButton = new QalculateButton(i18n("Down"), stackPage);
+ QToolTip::add(registerDownButton, i18n("Move selected register down"));
+ registerDownButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
+ stackPageButtonsLayout->addWidget(registerDownButton);
+ if(use_button_pixmaps) editRegisterButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("edit", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage);
+ else editRegisterButton = new QalculateButton(i18n("Edit"), stackPage);
+ QToolTip::add(editRegisterButton, i18n("Edit value of selected register"));
+ editRegisterButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
+ stackPageButtonsLayout->addWidget(editRegisterButton);
+ if(use_button_pixmaps) deleteRegisterButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("editdelete", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage);
+ else deleteRegisterButton = new QalculateButton(i18n("Delete"), stackPage);
+ QToolTip::add(deleteRegisterButton, i18n("Delete selected register"));
+ deleteRegisterButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
+ stackPageButtonsLayout->addWidget(deleteRegisterButton);
+ if(use_button_pixmaps) clearStackButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("view_remove", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage);
+ else clearStackButton = new QalculateButton(i18n("Clear"), stackPage);
+ QToolTip::add(clearStackButton, i18n("Clear the RPN stack"));
+ clearStackButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false);
+ registerUpButton->setEnabled(false);
+ registerDownButton->setEnabled(false);
+ editRegisterButton->setEnabled(false);
+ deleteRegisterButton->setEnabled(false);
+ clearStackButton->setEnabled(false);
+ stackPageButtonsLayout->addWidget(clearStackButton);
+ stackPageButtonsLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding));
+ mainStack->addWidget(stackPage, 2);
+
+ updateButtonWidths();
+
+ mainLayout->addWidget(mainStack);
+
+ QHBoxLayout *bottomLayout = new QHBoxLayout(0, 0, 6);
+ keypadButton = new QPushButton(i18n("Keypad"), centralWidget());
+ QToolTip::add(keypadButton, i18n("Show/hide keypad"));
+ keypadButton->setToggleButton(true);
+ bottomLayout->addWidget(keypadButton);
+ historyButton = new QPushButton(i18n("History"), centralWidget());
+ QToolTip::add(historyButton, i18n("Show/hide history"));
+ historyButton->setToggleButton(true);
+ bottomLayout->addWidget(historyButton);
+ stackButton = new QPushButton(i18n("RPN Stack"), centralWidget());
+ QToolTip::add(stackButton, i18n("Show/hide RPN stack"));
+ stackButton->setToggleButton(true);
+ bottomLayout->addWidget(stackButton);
+ if(!rpn_mode) stackButton->hide();
+ bottomLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ mainLayout->addLayout(bottomLayout);
+
+ connect(stackList, SIGNAL(selectionChanged()), this, SLOT(registerSelected()));
+ connect(stackList, SIGNAL(itemRenamed(QListViewItem*)), this, SLOT(stackRegisterSet(QListViewItem*)));
+ connect(stackList, SIGNAL(moved()), this, SLOT(stackRegisterMoved()));
+ connect(stackList, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)), this, SLOT(popupStackMenu(KListView*, QListViewItem*, const QPoint&)));
+ connect(registerUpButton, SIGNAL(clicked()), this, SLOT(registerUp()));
+ connect(registerDownButton, SIGNAL(clicked()), this, SLOT(registerDown()));
+ connect(editRegisterButton, SIGNAL(clicked()), this, SLOT(editRegister()));
+ connect(deleteRegisterButton, SIGNAL(clicked()), this, SLOT(deleteRegister()));
+ connect(clearStackButton, SIGNAL(clicked()), this, SLOT(clearStack()));
+ connect(stackButton, SIGNAL(toggled(bool)), this, SLOT(toggleStack(bool)));
+ connect(historyButton, SIGNAL(toggled(bool)), this, SLOT(toggleHistory(bool)));
+ connect(keypadButton, SIGNAL(toggled(bool)), this, SLOT(toggleKeypad(bool)));
+ connect(kp0, SIGNAL(clicked()), this, SLOT(insertKP0()));
+ connect(kp1, SIGNAL(clicked()), this, SLOT(insertKP1()));
+ connect(kp2, SIGNAL(clicked()), this, SLOT(insertKP2()));
+ connect(kp3, SIGNAL(clicked()), this, SLOT(insertKP3()));
+ connect(kp4, SIGNAL(clicked()), this, SLOT(insertKP4()));
+ connect(kp5, SIGNAL(clicked()), this, SLOT(insertKP5()));
+ connect(kp6, SIGNAL(clicked()), this, SLOT(insertKP6()));
+ connect(kp7, SIGNAL(clicked()), this, SLOT(insertKP7()));
+ connect(kp8, SIGNAL(clicked()), this, SLOT(insertKP8()));
+ connect(kp9, SIGNAL(clicked()), this, SLOT(insertKP9()));
+ connect(kpDot, SIGNAL(clicked()), this, SLOT(insertDot()));
+ connect(kpExp, SIGNAL(clicked()), this, SLOT(insertExp()));
+ connect(kpAns, SIGNAL(clicked()), this, SLOT(insertAns()));
+ connect(kpEquals, SIGNAL(clicked()), this, SLOT(execute()));
+ connect(kpPlus, SIGNAL(clicked()), this, SLOT(insertPlus()));
+ connect(kpMinus, SIGNAL(clicked()), this, SLOT(insertMinus()));
+ connect(kpTimes, SIGNAL(clicked()), this, SLOT(insertTimes()));
+ connect(kpDivision, SIGNAL(clicked()), this, SLOT(insertDivision()));
+ connect(kpDel, SIGNAL(clicked()), this, SLOT(expressionDel()));
+ connect(kpClear, SIGNAL(clicked()), this, SLOT(clearExpression()));
+ connect(kpSin, SIGNAL(clicked()), this, SLOT(insertSin()));
+ connect(kpCos, SIGNAL(clicked()), this, SLOT(insertCos()));
+ connect(kpTan, SIGNAL(clicked()), this, SLOT(insertTan()));
+ connect(kpSqrt, SIGNAL(clicked()), this, SLOT(insertSqrt()));
+ connect(kpLog, SIGNAL(clicked()), this, SLOT(insertLog()));
+ connect(kpLn, SIGNAL(clicked()), this, SLOT(insertLn()));
+ connect(kpRaise, SIGNAL(clicked()), this, SLOT(insertRaise()));
+ connect(kpSquare, SIGNAL(clicked()), this, SLOT(insertSquare()));
+ connect(kpFraction, SIGNAL(toggled(bool)), this, SLOT(setFractionMode(bool)));
+ connect(kpExact, SIGNAL(toggled(bool)), this, SLOT(setExactMode(bool)));
+ connect(kpAngleGroup, SIGNAL(clicked(int)), this, SLOT(kpSetAngleUnit(int)));
+ connect(kpBaseCombo->listBox(), SIGNAL(selected(int)), this, SLOT(kpSetBaseSelected(int)));
+ connect(kpBaseCombo, SIGNAL(activated(int)), this, SLOT(kpSetBase(int)));
+ connect(kpNumericCombo, SIGNAL(activated(int)), this, SLOT(kpSetNumericalMode(int)));
+ //connect(kpMod, SIGNAL(clicked()), this, SLOT(insertMod()));
+ connect(kpFactorial, SIGNAL(clicked()), this, SLOT(insertFactorial()));
+ //connect(expressionEdit, SIGNAL(returnPressed()), this, SLOT(execute()));
+ connect(expressionEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onExpressionChanged()));
+ connect(storeButton, SIGNAL(clicked()), this, SLOT(storeResult()));
+ connect(executeButton, SIGNAL(clicked()), this, SLOT(execute()));
+ connect(convertButton, SIGNAL(clicked()), this, SLOT(convertToUnitExpression()));
+ connect(functionsButton, SIGNAL(clicked()), this, SLOT(manageFunctions()));
+ connect(expressionEdit, SIGNAL(cursorMoved()), this, SLOT(displayParseStatus()));
+ connect(expressionEdit->qalculateCompletionBox, SIGNAL(hidden()), statusLabel_l, SLOT(update()));
+
+ //tab order
+ setTabOrder(expressionEdit, resultLabel);
+ setTabOrder(resultLabel, historyBrowser);
+ setTabOrder(historyBrowser, keypadButton);
+ setTabOrder(keypadButton, historyButton);
+ setTabOrder(historyButton, stackButton);
+
+ if(show_stack && rpn_mode) {
+ bottomLine->hide();
+ stackButton->setOn(true);
+ mainStack->raiseWidget(2);
+ mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
+ resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
+ } else if(show_keypad) {
+ bottomLine->hide();
+ keypadButton->setOn(true);
+ mainStack->raiseWidget(0);
+ mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
+ resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
+ } else if(show_history) {
+ bottomLine->hide();
+ historyButton->setOn(true);
+ mainStack->raiseWidget(1);
+ mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
+ resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
+ } else {
+ mainStack->hide();
+ mainStack->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum, false);
+ resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
+ }
+
+ initial_history = "";
+
+ for(QValueVector<QString>::size_type i = 0; i < inhistory.size(); i++) {
+ switch(inhistory_type[i]) {
+ case QALCULATE_HISTORY_EXPRESSION: {
+ if(i != 0) {
+ initial_history += "<br><hr>";
+ }
+ initial_history += "<a name=\"";
+ initial_history += QString::number(inhistory_id[i]);
+ initial_history += "\">";
+ initial_history += inhistory[i];
+ initial_history += "</a>";
+ initial_history += " ";
+ break;
+ }
+ case QALCULATE_HISTORY_REGISTER_MOVED: {
+ if(i != 0) {
+ initial_history += "<br><hr>";
+ }
+ initial_history += i18n("RPN Register Moved");
+ initial_history += "<br>";
+ break;
+ }
+ case QALCULATE_HISTORY_TRANSFORMATION: {
+ initial_history += "<i>";
+ initial_history += "<b>";
+ initial_history += inhistory[i];
+ initial_history += "</i>";
+ initial_history += ": ";
+ break;
+ }
+ case QALCULATE_HISTORY_RESULT: {
+ initial_history += "<a name=\"";
+ initial_history += QString::number(inhistory_id[i]);
+ initial_history += "\">";
+ initial_history += "= ";
+ initial_history += "</a>";
+ initial_history += "<b>";
+ initial_history += "<a name=\"";
+ initial_history += QString::number(inhistory_id[i]);
+ initial_history += "\">";
+ initial_history += inhistory[i];
+ initial_history += "</a>";
+ initial_history += "</b>";
+ initial_history += "<br>";
+ break;
+ }
+ case QALCULATE_HISTORY_RESULT_APPROXIMATE: {
+ initial_history += "<a name=\"";
+ initial_history += QString::number(inhistory_id[i]);
+ initial_history += "\">";
+ if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) historyBrowser)) {
+ initial_history += SIGN_ALMOST_EQUAL " ";
+ } else {
+ initial_history += "= ";
+ initial_history += i18n("approx.");
+ initial_history += " ";
+ }
+ initial_history += "</a>";
+ initial_history += "<b>";
+ initial_history += "<a name=\"";
+ initial_history += QString::number(inhistory_id[i]);
+ initial_history += "\">";
+ initial_history += inhistory[i];
+ initial_history += "</a>";
+ initial_history += "</b>";
+ initial_history += "<br>";
+ break;
+ }
+ case QALCULATE_HISTORY_PARSE: {
+ initial_history += "&nbsp;&nbsp;= ";
+ initial_history += "<font color=\"gray40\"><i>";
+ initial_history += "<a name=\"";
+ initial_history += QString::number(inhistory_id[i]);
+ initial_history += "\">";
+ initial_history += inhistory[i];
+ initial_history += "</a>";
+ initial_history += "</i></font>";
+ initial_history += "<br>";
+ break;
+ }
+ case QALCULATE_HISTORY_PARSE_APPROXIMATE: {
+ initial_history += "&nbsp;&nbsp;";
+ if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) historyBrowser)) {
+ initial_history += SIGN_ALMOST_EQUAL " ";
+ } else {
+ initial_history += "= ";
+ initial_history += i18n("approx.");
+ initial_history += " ";
+ }
+ initial_history += "<font color=\"gray40\"><i>";
+ initial_history += "<a name=\"";
+ initial_history += QString::number(inhistory_id[i]);
+ initial_history += "\">";
+ initial_history += inhistory[i];
+ initial_history += "</a>";
+ initial_history += "</i></font>";
+ initial_history += "<br>";
+ break;
+ }
+ case QALCULATE_HISTORY_WARNING: {
+ initial_history += "<font color=\"blue\">";
+ initial_history += "- ";
+ initial_history += inhistory[i];
+ initial_history += "</font>";
+ initial_history += "<br>";
+ break;
+ }
+ case QALCULATE_HISTORY_ERROR: {
+ initial_history += "<font color=\"red\">";
+ initial_history += "- ";
+ initial_history += inhistory[i];
+ initial_history += "</font>";
+ initial_history += "<br>";
+ break;
+ }
+ case QALCULATE_HISTORY_OLD: {
+ initial_history += inhistory[i];
+ initial_history += "<br>";
+ break;
+ }
+ }
+ }
+
+ historyBrowser->setText(initial_history);
+ initial_history = "";
+
+ if(use_custom_result_font) {
+ QFont new_font(resultLabel->font());
+ new_font.fromString(custom_result_font);
+ resultLabel->setFont(new_font);
+ } else {
+ resultLabel->unsetFont();
+ }
+ if(use_custom_expression_font) {
+ QFont new_font(expressionEdit->font());
+ new_font.fromString(custom_expression_font);
+ expressionEdit->setFont(new_font);
+ } else {
+ expressionEdit->unsetFont();
+ }
+ updateStatusLabelFonts();
+
+ set_unicode_buttons();
+
+ setupActions();
+
+ stackMenu = new QPopupMenu(this);
+ ActionEditRegister->plug(stackMenu);
+ ActionDeleteRegister->plug(stackMenu);
+ stackMenu->insertSeparator();
+ ActionClearStack->plug(stackMenu);
+
+ update_status_text();
+
+ bottomLine->setMinimumWidth(1000);
+
+ createGUI("qalculate_kdeui.rc");
+
+ menuBar()->sizeHint();
+ int h = menuBar()->height();
+ int w = 300;
+ while(menuBar()->heightForWidth(w) > h && w < 1000) {
+ w += 10;
+ }
+ if(w >= 1000) {
+ bottomLine->setMinimumWidth(0);
+ w = 0;
+ } else {
+ bottomLine->setMinimumWidth(w - 22);
+ }
+
+ if(!isShown()) adjustSize();
+ setAutoSaveSettings();
+
+ if(show_history || (rpn_mode && show_stack)) {
+ resize(QSize(10, height()).expandedTo(minimumSizeHint()));
+ } else if(show_keypad) {
+ resize(minimumSizeHint());
+ } else {
+ resize(QSize(width(), 10).expandedTo(minimumSizeHint()));
+ }
+
+ menu_functions = (QPopupMenu*) factory()->container("functions", this);
+ menu_variables = (QPopupMenu*) factory()->container("variables", this);
+ menu_units = (QPopupMenu*) factory()->container("units", this);
+ menu_to_unit = (QPopupMenu*) factory()->container("convert_to_unit", this);
+ menu_set_prefix = (QPopupMenu*) factory()->container("set_prefix", this);
+ menu_modes = (QPopupMenu*) factory()->container("modes", this);
+
+ QObject::connect(menu_modes, SIGNAL(activated(int)), this, SLOT(onModesMenuItemActivated(int)));
+ for(size_t i = 0; i < modes.size(); i++) {
+ menu_modes->insertItem(modes[i].name, -1, i);
+ if(i > 1) {
+ ModeObject *mo = new ModeObject(i);
+ mo->i_mode = i;
+ mode_objects.push_back(mo);
+ 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()));
+ }
+ }
+
+ QObject::connect(menu_functions, SIGNAL(activated(int)), this, SLOT(onFunctionMenuItemActivated(int)));
+ QObject::connect(menu_variables, SIGNAL(activated(int)), this, SLOT(onVariableMenuItemActivated(int)));
+ QObject::connect(menu_units, SIGNAL(activated(int)), this, SLOT(onUnitMenuItemActivated(int)));
+ QObject::connect(menu_to_unit, SIGNAL(activated(int)), this, SLOT(onConvertToUnitMenuItemActivated(int)));
+ QObject::connect(menu_set_prefix, SIGNAL(activated(int)), this, SLOT(onSetPrefixMenuItemActivated(int)));
+
+}
+
+KQalculate::~KQalculate() {}
+
+void KQalculate::updateStatusLabelFonts() {
+ if(use_custom_status_font) {
+ QFont new_font(statusLabel_l->font());
+ new_font.fromString(custom_status_font);
+ statusLabel_l->setFont(new_font);
+ new_font.setPointSizeFloat(new_font.pointSizeFloat() / 1.2);
+ statusLabel_r->setFont(new_font);
+ } else {
+ statusLabel_l->unsetFont();
+ statusLabel_r->unsetFont();
+ QFont new_font = statusLabel_l->font();
+ new_font.setPointSizeFloat(new_font.pointSizeFloat() / 1.2);
+ statusLabel_l->setFont(new_font);
+ new_font = statusLabel_r->font();
+ new_font.setPointSizeFloat(new_font.pointSizeFloat() / 1.44);
+ statusLabel_r->setFont(new_font);
+ }
+}
+
+void KQalculate::updateButtonWidths() {
+ int button_width = executeButton->sizeHint().width();
+ if(storeButton->sizeHint().width() > button_width) button_width = storeButton->sizeHint().width();
+ if(convertButton->sizeHint().width() > button_width) button_width = convertButton->sizeHint().width();
+ if(registerUpButton->sizeHint().width() > button_width) button_width = registerUpButton->sizeHint().width();
+ if(registerDownButton->sizeHint().width() > button_width) button_width = registerDownButton->sizeHint().width();
+ if(editRegisterButton->sizeHint().width() > button_width) button_width = editRegisterButton->sizeHint().width();
+ if(deleteRegisterButton->sizeHint().width() > button_width) button_width = deleteRegisterButton->sizeHint().width();
+ if(clearStackButton->sizeHint().width() > button_width) button_width = clearStackButton->sizeHint().width();
+ clearStackButton->setMinimumWidth(button_width);
+ executeButton->setMinimumWidth(button_width);
+}
+
+void KQalculate::fontChange(const QFont &old_font) {
+ updateStatusLabelFonts();
+ functionsButton->unsetFont();
+ QFont fb_font(functionsButton->font());
+ fb_font.setItalic(true);
+ functionsButton->setFont(fb_font);
+ kpSquare->setMarkup(i18n("x<sup>2</sup>"));
+ kpRaise->setMarkup(i18n("x<sup>y</sup>"));
+ result_display_updated();
+ KMainWindow::fontChange(old_font);
+ updateButtonWidths();
+}
+
+void KQalculate::showSystemTrayIcon(bool do_show) {
+ if(do_show && !trayicon) {
+ trayicon = new KSystemTray(this);
+ QObject::connect(trayicon, SIGNAL(quitSelected()), qApp, SLOT(quit()));
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ trayicon->setPixmap(loadSystrayIcon(PACKAGE));
+#else
+ trayicon->setPixmap(trayicon->loadIcon(PACKAGE));
+#endif
+#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 2
+ KPopupMenu* traypop = trayicon->contextMenu();
+ ActionHideSystemTrayIcon->plug(traypop, 1);
+#endif
+ QToolTip::add(trayicon, i18n("Qalculate! - Scientific Calculator"));
+ }
+ if(do_show) {
+ trayicon->show();
+ } else if(trayicon) {
+ trayicon->hide();
+ }
+}
+void KQalculate::hideSystemTrayIcon() {
+ showSystemTrayIcon(false);
+ close_to_systray = false;
+ show();
+}
+
+#define SET_TOGGLE_ACTION(action, value) action->blockSignals(true); action->setChecked(value); action->blockSignals(false);
+#define SET_TOGGLE_ACTION_ON(action) action->blockSignals(true); action->setChecked(true); action->blockSignals(false);
+
+void KQalculate::setupActions() {
+
+ ActionNewVariable = new KAction(i18n("Variable"), "filenew", 0, this, SLOT(newVariable()), actionCollection(), "new_variable");
+ ActionNewMatrix = new KAction(i18n("Matrix"), "filenew", 0, this, SLOT(newMatrix()), actionCollection(), "new_matrix");
+ ActionNewVector = new KAction(i18n("Vector"), "filenew", 0, this, SLOT(newVector()), actionCollection(), "new_vector");
+ ActionNewUnknownVariable = new KAction(i18n("Unknown Variable"), "filenew", 0, this, SLOT(newUnknownVariable()), actionCollection(), "new_unknown_variable");
+ ActionNewFunction = new KAction(i18n("Function"), "filenew", 0, this, SLOT(newFunction()), actionCollection(), "new_function");
+ ActionNewDataSet = new KAction(i18n("Data Set"), "filenew", 0, this, SLOT(newDataSet()), actionCollection(), "new_data_set");
+ ActionNewUnit = new KAction(i18n("Unit"), "filenew", 0, this, SLOT(newUnit()), actionCollection(), "new_unit");
+ ActionImportCSVFile = new KAction(i18n("Import CSV File..."), "fileimport", 0, this, SLOT(importCSVFile()), actionCollection(), "import_csv_file");
+ ActionExportCSVFile = new KAction(i18n("Export CSV File..."), "filexport", 0, this, SLOT(exportCSVFile()), actionCollection(), "export_csv_file");
+ ActionStoreResult = new KAction(i18n("Store Result..."), "filesave", CTRL+Key_S, this, SLOT(storeResult()), actionCollection(), "store_result");
+ ActionSaveAsImage = new KAction(i18n("Save Result Image..."), "filesave", 0, this, SLOT(saveAsImage()), actionCollection(), "save_as_image");
+ ActionSaveDefinitions = new KAction(i18n("Save Definitions"), "filesave", 0, this, SLOT(saveDefinitions()), actionCollection(), "save_definitions");
+ ActionUpdateExchangeRates = new KAction(i18n("Update Exchange Rates"), "reload", 0, this, SLOT(updateExchangeRates()), actionCollection(), "update_exchange_rates");
+ ActionPlotFunctionsData = new KAction(i18n("Plot Functions/Data"), 0, this, SLOT(plotFunctionsData()), actionCollection(), "plot_functions_data");
+ ActionPlotFunctionsData->setEnabled(canplot);
+ ActionConvertNumberBases = new KAction(i18n("Convert Number Bases"), 0, this, SLOT(convertNumberBases()), actionCollection(), "convert_number_bases");
+ ActionPeriodicTable = new KAction(i18n("Periodic Table"), 0, this, SLOT(periodicTable()), actionCollection(), "periodic_table");
+ if(close_to_systray) {
+ ActionClose = KStdAction::close(this, SLOT(close()), actionCollection());
+ } else {
+ ActionClose = NULL;
+ }
+ globalAccel = new KGlobalAccel(this);
+ globalAccel->insert("Show/hide Qalculate!", i18n("Show/hide main Qalculate! window"), QString::null, KShortcut(), KShortcut(), this, SLOT(showHide()));
+ globalAccel->readSettings();
+ globalAccel->updateConnections();
+ ActionConfigureGlobalShortcuts = new KAction(i18n("Configure &Global Shortcuts..."), "configure_shortcuts", 0, this, SLOT(configureGlobalShortcuts()), actionCollection(), "configure_global_shortcuts");
+ ActionQuit = KStdAction::quit(qApp, SLOT(quit()), actionCollection());
+ ActionManageVariables = new KAction(i18n("Manage Variables"), Key_F2, this, SLOT(manageVariables()), actionCollection(), "manage_variables");
+ ActionManageFunctions = new KAction(i18n("Manage Functions"), Key_F3, this, SLOT(manageFunctions()), actionCollection(), "manage_functions");
+ ActionManageUnits = new KAction(i18n("Manage Units"), Key_F4, this, SLOT(manageUnits()), actionCollection(), "manage_units");
+ ActionManageDataSets = new KAction(i18n("Manage Data Sets"), 0, this, SLOT(manageDataSets()), actionCollection(), "manage_data_sets");
+ ActionFactorize = new KAction(i18n("Factorize"), 0, this, SLOT(factorize()), actionCollection(), "factorize");
+ ActionSimplify = new KAction(i18n("Simplify"), 0, this, SLOT(simplify()), actionCollection(), "simplify");
+ ActionSetUnknowns = new KAction(i18n("Set Unknowns..."), 0, this, SLOT(setUnknowns()), actionCollection(), "set_unknowns");
+ ActionConvertToUnitExpression = new KAction(i18n("Convert to Unit Expression..."), CTRL+Key_T, this, SLOT(convertToUnitExpression()), actionCollection(), "convert_to_unit_expression");
+ ActionConvertToBaseUnits = new KAction(i18n("Convert to Base Units"), 0, this, SLOT(convertToBaseUnits()), actionCollection(), "convert_to_base_units");
+ ActionConvertToBestUnit = new KAction(i18n("Convert to Best Unit"), 0, this, SLOT(convertToBestUnit()), actionCollection(), "convert_to_best_unit");
+ ActionInsertMatrix = new KAction(i18n("Insert Matrix..."), 0, this, SLOT(insertMatrix()), actionCollection(), "insert_matrix");
+ ActionInsertVector = new KAction(i18n("Insert Vector..."), 0, this, SLOT(insertVector()), actionCollection(), "insert_vector");
+ ActionCopyResult = new KAction(i18n("Copy Result"), "editcopy", Key_F5, this, SLOT(copyResult()), actionCollection(), "copy_result");
+ ActionClearHistory = new KAction(i18n("Clear History"), "editclear", 0, this, SLOT(clearHistory()), actionCollection(), "clear_history");
+ ActionPreferences = new KAction(i18n("Configure Qalculate!"), "configure", 0, this, SLOT(preferences()), actionCollection(), "preferences");
+ KStdAction::keyBindings(guiFactory(), SLOT(configureShortcuts()), actionCollection(), "keybindings");
+ ActionNumberBaseBinary = new KRadioAction(i18n("Binary"), 0, this, SLOT(numberBaseBinary()), actionCollection(), "number_base_binary");
+ ActionNumberBaseBinary->setExclusiveGroup("group_number_base");
+ ActionNumberBaseOctal = new KRadioAction(i18n("Octal"), 0, this, SLOT(numberBaseOctal()), actionCollection(), "number_base_octal");
+ ActionNumberBaseOctal->setExclusiveGroup("group_number_base");
+ ActionNumberBaseDecimal = new KRadioAction(i18n("Decimal"), 0, this, SLOT(numberBaseDecimal()), actionCollection(), "number_base_decimal");
+ ActionNumberBaseDecimal->setExclusiveGroup("group_number_base");
+ ActionNumberBaseHexadecimal = new KRadioAction(i18n("Hexadecimal"), 0, this, SLOT(numberBaseHexadecimal()), actionCollection(), "number_base_hexadecimal");
+ ActionNumberBaseHexadecimal->setExclusiveGroup("group_number_base");
+ ActionNumberBaseOther = new KRadioAction(i18n("Other..."), 0, this, SLOT(numberBaseOther()), actionCollection(), "number_base_other");
+ ActionNumberBaseOther->setExclusiveGroup("group_number_base");
+ ActionNumberBaseSexagesimal = new KRadioAction(i18n("Sexagesimal"), 0, this, SLOT(numberBaseSexagesimal()), actionCollection(), "number_base_sexagesimal");
+ ActionNumberBaseSexagesimal->setExclusiveGroup("group_number_base");
+ ActionNumberBaseTimeFormat = new KRadioAction(i18n("Time Format"), 0, this, SLOT(numberBaseTimeFormat()), actionCollection(), "number_base_time_format");
+ ActionNumberBaseTimeFormat->setExclusiveGroup("group_number_base");
+ ActionNumberBaseRomanNumerals = new KRadioAction(i18n("Roman Numerals"), 0, this, SLOT(numberBaseRomanNumerals()), actionCollection(), "number_base_roman_numerals");
+ ActionNumberBaseRomanNumerals->setExclusiveGroup("group_number_base");
+ ActionSetBase = new KAction(i18n("Select Result and Expression Base..."), CTRL+Key_B, this, SLOT(setBase()), actionCollection(), "set_base");
+ ActionNumericalDisplayNormal = new KRadioAction(i18n("Normal"), 0, this, SLOT(numericalDisplayNormal()), actionCollection(), "numerical_display_normal");
+ ActionNumericalDisplayNormal->setExclusiveGroup("group_numberical_display");
+ ActionNumericalDisplayEngineering = new KRadioAction(i18n("Engineering"), 0, this, SLOT(numericalDisplayEngineering()), actionCollection(), "numerical_display_engineering");
+ ActionNumericalDisplayEngineering->setExclusiveGroup("group_numberical_display");
+ ActionNumericalDisplayScientific = new KRadioAction(i18n("Scientific"), 0, this, SLOT(numericalDisplayScientific()), actionCollection(), "numerical_display_scientific");
+ ActionNumericalDisplayScientific->setExclusiveGroup("group_numberical_display");
+ ActionNumericalDisplayPurelyScientific = new KRadioAction(i18n("Purely Scientific"), 0, this, SLOT(numericalDisplayPurelyScientific()), actionCollection(), "numerical_display_purely_scientific");
+ ActionNumericalDisplayPurelyScientific->setExclusiveGroup("group_numberical_display");
+ ActionNumericalDisplaySimple = new KRadioAction(i18n("Simple"), 0, this, SLOT(numericalDisplaySimple()), actionCollection(), "numerical_display_simple");
+ ActionNumericalDisplaySimple->setExclusiveGroup("group_numberical_display");
+ ActionIndicateInfiniteSeries = new KToggleAction(i18n("Indicate Infinite Series"), 0, actionCollection(), "indicate_infinite_series");
+ QObject::connect(ActionIndicateInfiniteSeries, SIGNAL(toggled(bool)), this, SLOT(indicateInfiniteSeries(bool)));
+ ActionSortMinusLast = new KToggleAction(i18n("Sort Minus Last"), 0, actionCollection(), "sort_minus_last");
+ QObject::connect(ActionSortMinusLast, SIGNAL(toggled(bool)), this, SLOT(sortMinusLast(bool)));
+ ActionNegativeExponents = new KToggleAction(i18n("Negative Exponents"), 0, actionCollection(), "negative_exponents");
+ QObject::connect(ActionNegativeExponents, SIGNAL(toggled(bool)), this, SLOT(negativeExponents(bool)));
+ ActionShowEndingZeroes = new KToggleAction(i18n("Show Ending Zeroes"), 0, actionCollection(), "show_ending_zeroes");
+ QObject::connect(ActionShowEndingZeroes, SIGNAL(toggled(bool)), this, SLOT(showEndingZeroes(bool)));
+ ActionRoundHalfwayNumbersToEven = new KToggleAction(i18n("Round Halfway Numbers to Even"), 0, actionCollection(), "round_halfway_numbers_to_even");
+ QObject::connect(ActionRoundHalfwayNumbersToEven, SIGNAL(toggled(bool)), this, SLOT(roundHalfwayNumbersToEven(bool)));
+ ActionFractionalDisplayDecimal = new KRadioAction(i18n("Decimal"), 0, this, SLOT(fractionalDisplayDecimal()), actionCollection(), "fractional_display_decimal");
+ ActionFractionalDisplayDecimal->setExclusiveGroup("group_fractional_display");
+ ActionFractionalDisplayDecimalTryExact = new KRadioAction(i18n("Decimal (Try Exact)"), 0, this, SLOT(fractionalDisplayDecimalTryExact()), actionCollection(), "fractional_display_decimal_try_exact");
+ ActionFractionalDisplayDecimalTryExact->setExclusiveGroup("group_fractional_display");
+ ActionFractionalDisplayFraction = new KRadioAction(i18n("Fraction"), 0, this, SLOT(fractionalDisplayFraction()), actionCollection(), "fractional_display_fraction");
+ ActionFractionalDisplayFraction->setExclusiveGroup("group_fractional_display");
+ ActionFractionalDisplayCombined = new KRadioAction(i18n("Combined"), 0, this, SLOT(fractionalDisplayCombined()), actionCollection(), "fractional_display_combined");
+ ActionFractionalDisplayCombined->setExclusiveGroup("group_fractional_display");
+ ActionEnablePrefixes = new KToggleAction(i18n("Enable Prefixes"), 0, actionCollection(), "enable_prefixes");
+ QObject::connect(ActionEnablePrefixes, SIGNAL(toggled(bool)), this, SLOT(enablePrefixes(bool)));
+ ActionEnableUseOfAllPrefixes = new KToggleAction(i18n("Enable Use of All SI Prefixes"), 0, actionCollection(), "enable_use_of_all_prefixes");
+ QObject::connect(ActionEnableUseOfAllPrefixes, SIGNAL(toggled(bool)), this, SLOT(enableUseOfAllPrefixes(bool)));
+ ActionEnableDenominatorPrefixes = new KToggleAction(i18n("Enable Denominator Prefixes"), 0, actionCollection(), "enable_denominator_prefixes");
+ QObject::connect(ActionEnableDenominatorPrefixes, SIGNAL(toggled(bool)), this, SLOT(enableDenominatorPrefixes(bool)));
+ ActionPlaceUnitsSeparately = new KToggleAction(i18n("Place Units Separately"), 0, actionCollection(), "place_units_separately");
+ QObject::connect(ActionPlaceUnitsSeparately, SIGNAL(toggled(bool)), this, SLOT(placeUnitsSeparately(bool)));
+ ActionAutoNoConversion = new KRadioAction(i18n("No Automatic Conversion"), 0, this, SLOT(autoNoConversion()), actionCollection(), "auto_no_conversion");
+ ActionAutoNoConversion->setExclusiveGroup("group_auto_conversion");
+ ActionAutoConvertToBaseUnits = new KRadioAction(i18n("Convert to Base Units"), 0, this, SLOT(autoConvertToBaseUnits()), actionCollection(), "auto_convert_to_base_units");
+ ActionAutoConvertToBaseUnits->setExclusiveGroup("group_auto_conversion");
+ ActionAutoConvertToBestUnit = new KRadioAction(i18n("Convert to Best Unit"), 0, this, SLOT(autoConvertToBestUnit()), actionCollection(), "auto_convert_to_best_unit");
+ ActionAutoConvertToBestUnit->setExclusiveGroup("group_auto_conversion");
+ ActionAngleUnitDegrees = new KRadioAction(i18n("Degrees"), 0, this, SLOT(angleUnitDegrees()), actionCollection(), "angle_unit_degrees");
+ ActionAngleUnitDegrees->setExclusiveGroup("group_angle_unit");
+ ActionAngleUnitRadians = new KRadioAction(i18n("Radians"), 0, this, SLOT(angleUnitRadians()), actionCollection(), "angle_unit_radians");
+ ActionAngleUnitRadians->setExclusiveGroup("group_angle_unit");
+ ActionAngleUnitGradians = new KRadioAction(i18n("Gradians"), 0, this, SLOT(angleUnitGradians()), actionCollection(), "angle_unit_gradians");
+ ActionAngleUnitGradians->setExclusiveGroup("group_angle_unit");
+ ActionAngleUnitNone = new KRadioAction(i18n("None"), 0, this, SLOT(angleUnitNone()), actionCollection(), "angle_unit_none");
+ ActionAngleUnitNone->setExclusiveGroup("group_angle_unit");
+ ActionAbbreviateNames = new KToggleAction(i18n("Abbreviate Names"), 0, actionCollection(), "abbreviate_names");
+ QObject::connect(ActionAbbreviateNames, SIGNAL(toggled(bool)), this, SLOT(abbreviateNames(bool)));
+ ActionEnableVariables = new KToggleAction(i18n("Enable Variables"), 0, actionCollection(), "enable_variables");
+ QObject::connect(ActionEnableVariables, SIGNAL(toggled(bool)), this, SLOT(enableVariables(bool)));
+ ActionEnableFunctions = new KToggleAction(i18n("Enable Functions"), 0, actionCollection(), "enable_functions");
+ QObject::connect(ActionEnableFunctions, SIGNAL(toggled(bool)), this, SLOT(enableFunctions(bool)));
+ ActionEnableUnits = new KToggleAction(i18n("Enable Units"), 0, actionCollection(), "enable_units");
+ QObject::connect(ActionEnableUnits, SIGNAL(toggled(bool)), this, SLOT(enableUnits(bool)));
+ ActionEnableUnknowns = new KToggleAction(i18n("Enable Unknowns"), 0, actionCollection(), "enable_unknowns");
+ QObject::connect(ActionEnableUnknowns, SIGNAL(toggled(bool)), this, SLOT(enableUnknowns(bool)));
+ ActionCalculateVariables = new KToggleAction(i18n("Calculate Variables"), 0, actionCollection(), "calculate_variables");
+ QObject::connect(ActionCalculateVariables, SIGNAL(toggled(bool)), this, SLOT(calculateVariables(bool)));
+ ActionAllowComplexResult = new KToggleAction(i18n("Allow Complex Result"), 0, actionCollection(), "allow_complex_result");
+ QObject::connect(ActionAllowComplexResult, SIGNAL(toggled(bool)), this, SLOT(allowComplexResult(bool)));
+ ActionAllowInfiniteResult = new KToggleAction(i18n("Allow Infinite Result"), 0, actionCollection(), "allow_infinite_result");
+ QObject::connect(ActionAllowInfiniteResult, SIGNAL(toggled(bool)), this, SLOT(allowInfiniteResult(bool)));
+ ActionApproximationTryExact = new KRadioAction(i18n("Try Exact"), 0, this, SLOT(approximationTryExact()), actionCollection(), "approximation_try_exact");
+ ActionApproximationTryExact->setExclusiveGroup("group_approximation");
+ ActionApproximationAlwaysExact = new KRadioAction(i18n("Always Exact"), 0, this, SLOT(approximationAlwaysExact()), actionCollection(), "approximation_always_exact");
+ ActionApproximationAlwaysExact->setExclusiveGroup("group_approximation");
+ ActionApproximationApproximate = new KRadioAction(i18n("Approximate"), 0, this, SLOT(approximationApproximate()), actionCollection(), "approximation_approximate");
+ ActionApproximationApproximate->setExclusiveGroup("group_approximation");
+ ActionAssumptionTypeUnknown = new KRadioAction(i18n("Unknown"), 0, this, SLOT(assumptionTypeUnknown()), actionCollection(), "assumption_type_unknown");
+ ActionAssumptionTypeUnknown->setExclusiveGroup("group_assumption_type");
+ ActionAssumptionTypeNonMatrix = new KRadioAction(i18n("Not Matrix"), 0, this, SLOT(assumptionTypeNonMatrix()), actionCollection(), "assumption_type_nonmatrix");
+ ActionAssumptionTypeNonMatrix->setExclusiveGroup("group_assumption_type");
+ ActionAssumptionTypeNumber = new KRadioAction(i18n("Number"), 0, this, SLOT(assumptionTypeNumber()), actionCollection(), "assumption_type_number");
+ ActionAssumptionTypeNumber->setExclusiveGroup("group_assumption_type");
+ ActionAssumptionTypeComplex = new KRadioAction(i18n("Complex"), 0, this, SLOT(assumptionTypeComplex()), actionCollection(), "assumption_type_complex");
+ ActionAssumptionTypeComplex->setExclusiveGroup("group_assumption_type");
+ ActionAssumptionTypeReal = new KRadioAction(i18n("Real"), 0, this, SLOT(assumptionTypeReal()), actionCollection(), "assumption_type_real");
+ ActionAssumptionTypeReal->setExclusiveGroup("group_assumption_type");
+ ActionAssumptionTypeRational = new KRadioAction(i18n("Rational"), 0, this, SLOT(assumptionTypeRational()), actionCollection(), "assumption_type_rational");
+ ActionAssumptionTypeRational->setExclusiveGroup("group_assumption_type");
+ ActionAssumptionTypeInteger = new KRadioAction(i18n("Integer"), 0, this, SLOT(assumptionTypeInteger()), actionCollection(), "assumption_type_integer");
+ ActionAssumptionTypeInteger->setExclusiveGroup("group_assumption_type");
+ ActionAssumptionSignUnknown = new KRadioAction(i18n("Unknown"), 0, this, SLOT(assumptionSignUnknown()), actionCollection(), "assumption_sign_unknown");
+ ActionAssumptionSignUnknown->setExclusiveGroup("group_assumption_sign");
+ ActionAssumptionSignNonZero = new KRadioAction(i18n("Non-Zero"), 0, this, SLOT(assumptionSignNonZero()), actionCollection(), "assumption_sign_non_zero");
+ ActionAssumptionSignNonZero->setExclusiveGroup("group_assumption_sign");
+ ActionAssumptionSignPositive = new KRadioAction(i18n("Positive"), 0, this, SLOT(assumptionSignPositive()), actionCollection(), "assumption_sign_positive");
+ ActionAssumptionSignPositive->setExclusiveGroup("group_assumption_sign");
+ ActionAssumptionSignNonNegative = new KRadioAction(i18n("Non-Negative"), 0, this, SLOT(assumptionSignNonNegative()), actionCollection(), "assumption_sign_non_negative");
+ ActionAssumptionSignNonNegative->setExclusiveGroup("group_assumption_sign");
+ ActionAssumptionSignNegative = new KRadioAction(i18n("Negative"), 0, this, SLOT(assumptionSignNegative()), actionCollection(), "assumption_sign_negative");
+ ActionAssumptionSignNegative->setExclusiveGroup("group_assumption_sign");
+ ActionAssumptionSignNonPositive = new KRadioAction(i18n("Non-Positive"), 0, this, SLOT(assumptionSignNonPositive()), actionCollection(), "assumption_sign_non_positive");
+ ActionAssumptionSignNonPositive->setExclusiveGroup("group_assumption_sign");
+ ActionNonZeroDenominators = new KToggleAction(i18n("Non-Zero Denominators"), 0, actionCollection(), "non_zero_denominators");
+ QObject::connect(ActionNonZeroDenominators, SIGNAL(toggled(bool)), this, SLOT(nonZeroDenominators(bool)));
+ ActionWarnAboutDenominatorsAssumedNonZero = new KToggleAction(i18n("Warn About Denominators Assumed Non-Zero"), 0, actionCollection(), "warn_about_denominators_assumed_nonzero");
+ QObject::connect(ActionWarnAboutDenominatorsAssumedNonZero, SIGNAL(toggled(bool)), this, SLOT(warnAboutDenominatorsAssumedNonZero(bool)));
+ ActionAlgebraicModeSimplify = new KRadioAction(i18n("Simplify"), 0, this, SLOT(algebraicModeSimplify()), actionCollection(), "algebraic_mode_simplify");
+ ActionAlgebraicModeSimplify->setExclusiveGroup("group_alebraic_mode");
+ ActionAlgebraicModeFactorize = new KRadioAction(i18n("Factorize"), 0, this, SLOT(algebraicModeFactorize()), actionCollection(), "algebraic_mode_factorize");
+ ActionAlgebraicModeFactorize->setExclusiveGroup("group_alebraic_mode");
+ ActionAlgebraicModeNone = new KRadioAction(i18n("None"), 0, this, SLOT(algebraicModeNone()), actionCollection(), "algebraic_mode_none");
+ ActionAlgebraicModeNone->setExclusiveGroup("group_alebraic_mode");
+ ActionReadPrecision = new KToggleAction(i18n("Read Precision"), 0, actionCollection(), "read_precision");
+ QObject::connect(ActionReadPrecision, SIGNAL(toggled(bool)), this, SLOT(readPrecision(bool)));
+ ActionLimitImplicitMultiplication = new KToggleAction(i18n("Limit Implicit Multiplication"), 0, actionCollection(), "limit_implicit_multiplication");
+ QObject::connect(ActionLimitImplicitMultiplication, SIGNAL(toggled(bool)), this, SLOT(limitImplicitMultiplication(bool)));
+ ActionRPNMode = new KToggleAction(i18n("RPN Mode"), CTRL+Key_R, actionCollection(), "rpn_mode");
+ QObject::connect(ActionRPNMode, SIGNAL(toggled(bool)), this, SLOT(rpnMode(bool)));
+ ActionRPNSyntax = new KToggleAction(i18n("RPN Syntax"), 0, actionCollection(), "rpn_syntax");
+ QObject::connect(ActionRPNSyntax, SIGNAL(toggled(bool)), this, SLOT(rpnSyntax(bool)));
+ ActionPrecision = new KAction(i18n("Precision"), 0, this, SLOT(precision()), actionCollection(), "precision");
+ ActionDecimals = new KAction(i18n("Decimals"), 0, this, SLOT(decimals()), actionCollection(), "decimals");
+ ActionSaveModeAs = new KAction(i18n("Save Mode..."), "filesave", 0, this, SLOT(saveModeAs()), actionCollection(), "save_mode_as");
+ ActionDeleteMode = new KAction(i18n("Delete Mode..."), "editdelete", 0, this, SLOT(deleteMode()), actionCollection(), "delete_mode");
+ ActionDeleteMode->setEnabled(modes.size() > 2);
+ ActionSaveMode = new KAction(i18n("Save Default Mode"), "filesave", 0, this, SLOT(saveMode()), actionCollection(), "save_mode");
+ ActionClearStack = new KAction(i18n("Clear Stack"), "view_remove", 0, this, SLOT(clearStack()), actionCollection(), "clear_stack");
+ ActionDeleteRegister = new KAction(i18n("Delete"), "editdelete", 0, this, SLOT(deleteRegister()), actionCollection(), "delete_register");
+ ActionEditRegister = new KAction(i18n("Edit"), "edit", 0, this, SLOT(editRegister()), actionCollection(), "edit_register");
+
+ new KAction(i18n("Exp RPN Operation"), CTRL+SHIFT+Key_E, this, SLOT(insertExp()), actionCollection(), "rpn_exp10");
+
+ setModeActions();
+
+}
+void KQalculate::setAssumptionsMenu() {
+ switch(CALCULATOR->defaultAssumptions()->sign()) {
+ case ASSUMPTION_SIGN_POSITIVE: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignPositive); break;}
+ case ASSUMPTION_SIGN_NONPOSITIVE: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignNonPositive); break;}
+ case ASSUMPTION_SIGN_NEGATIVE: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignNegative); break;}
+ case ASSUMPTION_SIGN_NONNEGATIVE: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignNonNegative); break;}
+ case ASSUMPTION_SIGN_NONZERO: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignNonZero); break;}
+ default: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignUnknown); }
+ }
+ switch(CALCULATOR->defaultAssumptions()->type()) {
+ case ASSUMPTION_TYPE_INTEGER: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeInteger); break;}
+ case ASSUMPTION_TYPE_RATIONAL: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeRational); break;}
+ case ASSUMPTION_TYPE_COMPLEX: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeComplex); break;}
+ case ASSUMPTION_TYPE_NUMBER: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeNumber); break;}
+ case ASSUMPTION_TYPE_REAL: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeReal); break;}
+ case ASSUMPTION_TYPE_NONMATRIX: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeNonMatrix); break;}
+ default: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeUnknown); }
+ }
+}
+void KQalculate::setModeActions() {
+
+ SET_TOGGLE_ACTION(ActionAllowComplexResult, evalops.allow_complex)
+ SET_TOGGLE_ACTION(ActionAllowInfiniteResult, evalops.allow_infinite)
+ SET_TOGGLE_ACTION(ActionEnableVariables, evalops.parse_options.variables_enabled)
+ SET_TOGGLE_ACTION(ActionEnableFunctions, evalops.parse_options.functions_enabled)
+ SET_TOGGLE_ACTION(ActionEnableUnits, evalops.parse_options.units_enabled)
+ SET_TOGGLE_ACTION(ActionEnableUnknowns, evalops.parse_options.unknowns_enabled)
+ SET_TOGGLE_ACTION(ActionCalculateVariables, evalops.calculate_variables)
+ SET_TOGGLE_ACTION(ActionReadPrecision, evalops.parse_options.read_precision != DONT_READ_PRECISION)
+ SET_TOGGLE_ACTION(ActionLimitImplicitMultiplication, evalops.parse_options.limit_implicit_multiplication)
+ SET_TOGGLE_ACTION(ActionRPNSyntax, evalops.parse_options.rpn)
+ SET_TOGGLE_ACTION(ActionRPNMode, rpn_mode)
+ SET_TOGGLE_ACTION(ActionNonZeroDenominators, evalops.assume_denominators_nonzero)
+ SET_TOGGLE_ACTION(ActionWarnAboutDenominatorsAssumedNonZero, evalops.warn_about_denominators_assumed_nonzero)
+ SET_TOGGLE_ACTION(ActionAbbreviateNames, printops.abbreviate_names)
+ SET_TOGGLE_ACTION(ActionIndicateInfiniteSeries, printops.indicate_infinite_series)
+ SET_TOGGLE_ACTION(ActionSortMinusLast, printops.sort_options.minus_last)
+ SET_TOGGLE_ACTION(ActionNegativeExponents, printops.negative_exponents)
+ SET_TOGGLE_ACTION(ActionShowEndingZeroes, printops.show_ending_zeroes)
+ SET_TOGGLE_ACTION(ActionRoundHalfwayNumbersToEven, printops.round_halfway_to_even)
+ SET_TOGGLE_ACTION(ActionEnablePrefixes, printops.use_unit_prefixes)
+ SET_TOGGLE_ACTION(ActionEnableUseOfAllPrefixes, printops.use_all_prefixes)
+ SET_TOGGLE_ACTION(ActionEnableDenominatorPrefixes, printops.use_denominator_prefix)
+ SET_TOGGLE_ACTION(ActionPlaceUnitsSeparately, printops.place_units_separately)
+
+ kpExact->blockSignals(true);
+ switch(evalops.approximation) {
+ case APPROXIMATION_EXACT: {
+ SET_TOGGLE_ACTION_ON(ActionApproximationAlwaysExact);
+ kpExact->setOn(true);
+ break;
+ }
+ case APPROXIMATION_TRY_EXACT: {
+ SET_TOGGLE_ACTION_ON(ActionApproximationTryExact);
+ kpExact->setOn(false);
+ break;
+ }
+ case APPROXIMATION_APPROXIMATE: {
+ SET_TOGGLE_ACTION_ON(ActionApproximationApproximate);
+ kpExact->setOn(false);
+ break;
+ }
+ }
+ kpExact->blockSignals(false);
+ switch(evalops.auto_post_conversion) {
+ case POST_CONVERSION_BEST: {
+ SET_TOGGLE_ACTION_ON(ActionAutoConvertToBestUnit);
+ break;
+ }
+ case POST_CONVERSION_BASE: {
+ SET_TOGGLE_ACTION_ON(ActionAutoConvertToBaseUnits);
+ break;
+ }
+ default: {
+ SET_TOGGLE_ACTION_ON(ActionAutoNoConversion);
+ }
+ }
+ kpAngleGroup->blockSignals(true);
+ switch(evalops.parse_options.angle_unit) {
+ case ANGLE_UNIT_DEGREES: {
+ SET_TOGGLE_ACTION_ON(ActionAngleUnitDegrees);
+ kpAngleGroup->setButton(0);
+ break;
+ }
+ case ANGLE_UNIT_RADIANS: {
+ SET_TOGGLE_ACTION_ON(ActionAngleUnitRadians);
+ kpAngleGroup->setButton(1);
+ break;
+ }
+ case ANGLE_UNIT_GRADIANS: {
+ SET_TOGGLE_ACTION_ON(ActionAngleUnitGradians);
+ kpAngleGroup->setButton(2);
+ break;
+ }
+ default: {
+ SET_TOGGLE_ACTION_ON(ActionAngleUnitNone);
+ kpAngleGroup->setButton(3);
+ }
+ }
+ kpAngleGroup->blockSignals(false);
+
+ kpBaseCombo->blockSignals(true);
+ switch(printops.base) {
+ case BASE_BINARY: {
+ SET_TOGGLE_ACTION_ON(ActionNumberBaseBinary);
+ kpBaseCombo->setCurrentItem(0);
+ break;
+ }
+ case BASE_OCTAL: {
+ SET_TOGGLE_ACTION_ON(ActionNumberBaseOctal);
+ kpBaseCombo->setCurrentItem(1);
+ break;
+ }
+ case BASE_DECIMAL: {
+ SET_TOGGLE_ACTION_ON(ActionNumberBaseDecimal);
+ kpBaseCombo->setCurrentItem(2);
+ break;
+ }
+ case BASE_HEXADECIMAL: {
+ SET_TOGGLE_ACTION_ON(ActionNumberBaseHexadecimal);
+ kpBaseCombo->setCurrentItem(3);
+ break;
+ }
+ case BASE_ROMAN_NUMERALS: {
+ SET_TOGGLE_ACTION_ON(ActionNumberBaseRomanNumerals);
+ kpBaseCombo->setCurrentItem(6);
+ break;
+ }
+ case BASE_SEXAGESIMAL: {
+ SET_TOGGLE_ACTION_ON(ActionNumberBaseSexagesimal);
+ kpBaseCombo->setCurrentItem(4);
+ break;
+ }
+ case BASE_TIME: {
+ SET_TOGGLE_ACTION_ON(ActionNumberBaseTimeFormat);
+ kpBaseCombo->setCurrentItem(5);
+ break;
+ }
+ default: {
+ SET_TOGGLE_ACTION_ON(ActionNumberBaseOther);
+ kpBaseCombo->setCurrentItem(7);
+ }
+ }
+ kpBaseCombo->blockSignals(false);
+
+ kpNumericCombo->blockSignals(true);
+ switch(printops.min_exp) {
+ case EXP_PRECISION: {
+ SET_TOGGLE_ACTION_ON(ActionNumericalDisplayNormal);
+ kpNumericCombo->setCurrentItem(0);
+ break;
+ }
+ case EXP_BASE_3: {
+ SET_TOGGLE_ACTION_ON(ActionNumericalDisplayEngineering);
+ kpNumericCombo->setCurrentItem(1);
+ break;
+ }
+ case EXP_SCIENTIFIC: {
+ SET_TOGGLE_ACTION_ON(ActionNumericalDisplayScientific);
+ kpNumericCombo->setCurrentItem(2);
+ break;
+ }
+ case EXP_PURE: {
+ SET_TOGGLE_ACTION_ON(ActionNumericalDisplayPurelyScientific);
+ kpNumericCombo->setCurrentItem(3);
+ break;
+ }
+ case EXP_NONE: {
+ SET_TOGGLE_ACTION_ON(ActionNumericalDisplaySimple);
+ kpNumericCombo->setCurrentItem(4);
+ break;
+ }
+ }
+ kpNumericCombo->blockSignals(false);
+
+ kpFraction->blockSignals(true);
+ switch (printops.number_fraction_format) {
+ case FRACTION_DECIMAL: {
+ SET_TOGGLE_ACTION_ON(ActionFractionalDisplayDecimal);
+ kpFraction->setOn(false);
+ break;
+ }
+ case FRACTION_DECIMAL_EXACT: {
+ SET_TOGGLE_ACTION_ON(ActionFractionalDisplayDecimalTryExact);
+ kpFraction->setOn(false);
+ break;
+ }
+ case FRACTION_COMBINED: {
+ SET_TOGGLE_ACTION_ON(ActionFractionalDisplayCombined);
+ kpFraction->setOn(true);
+ break;
+ }
+ case FRACTION_FRACTIONAL: {
+ SET_TOGGLE_ACTION_ON(ActionFractionalDisplayFraction);
+ kpFraction->setOn(true);
+ break;
+ }
+ }
+ kpFraction->blockSignals(false);
+
+ setAssumptionsMenu();
+ switch(evalops.structuring) {
+ case STRUCTURING_SIMPLIFY: {SET_TOGGLE_ACTION_ON(ActionAlgebraicModeSimplify); break;}
+ case STRUCTURING_FACTORIZE: {SET_TOGGLE_ACTION_ON(ActionAlgebraicModeFactorize); break;}
+ default: {SET_TOGGLE_ACTION_ON(ActionAlgebraicModeNone); }
+ }
+
+}
+
+#define TEXT_TAGS "<font size=6>"
+#define TEXT_TAGS_END "</font>"
+#define TEXT_TAGS_SMALL "<font size=5>"
+#define TEXT_TAGS_SMALL_END "</font>"
+#define TEXT_TAGS_XSMALL "<font size=4>"
+#define TEXT_TAGS_XSMALL_END "</font>"
+
+#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;}
+
+#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;}
+
+#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);
+
+#define STR_MARKUP_BEGIN(str) if(ips.power_depth > 0) {str += TEXT_TAGS "<sup>";}
+#define STR_MARKUP_END(str) if(ips.power_depth > 0) {str +="</sup>" TEXT_TAGS_END;}
+
+#define STR_MARKUP_BEGIN_SMALL(str) if(ips.power_depth > 0) {str += TEXT_TAGS_SMALL "<sup>";} else {str += TEXT_TAGS_SMALL;}
+#define STR_MARKUP_END_SMALL(str) if(ips.power_depth > 0) {str +="</sup>" TEXT_TAGS_SMALL_END;} else {str += TEXT_TAGS_SMALL_END;}
+
+#define STR_MARKUP_BEGIN_CURSIVE(str) if(ips.power_depth > 0) {str += TEXT_TAGS "<i><sup>";} else {str += "<i>";}
+#define STR_MARKUP_END_CURSIVE(str) if(ips.power_depth > 0) {str +="</sup></i>" TEXT_TAGS_END;} else {str += "</i>";}
+
+QString draw_structure(MathStructure &m, const QFont &font, const QColorGroup &cg, PrintOptions po = default_print_options, InternalPrintStruct ips = top_ips, bool in_matrix = false) {
+
+ if(ips.depth == 0 && po.is_approximate) *po.is_approximate = false;
+
+ QString mstr;
+
+ InternalPrintStruct ips_n = ips;
+ if(m.isApproximate()) ips_n.parent_approximate = true;
+ if(m.precision() > 0 && (ips_n.parent_precision < 1 || m.precision() < ips_n.parent_precision)) ips_n.parent_precision = m.precision();
+ switch(m.type()) {
+ case STRUCT_NUMBER: {
+ string exp = "";
+ bool exp_minus;
+ ips_n.exp = &exp;
+ ips_n.exp_minus = &exp_minus;
+ STR_MARKUP_BEGIN(mstr);
+ mstr += m.number().print(po, ips_n).c_str();
+ if(!exp.empty()) {
+ if(po.lower_case_e) {
+ mstr += "e";
+ } else {
+ STR_MARKUP_ADD_SMALL(mstr, "E");
+ }
+ if(exp_minus) {
+ mstr += "-";
+ }
+ mstr += exp.c_str();
+ }
+ if(po.base != BASE_DECIMAL && po.base != BASE_HEXADECIMAL && po.base > 0 && po.base <= 36) {
+ if(ips.power_depth == 0) {
+ mstr += "<sub>";
+ mstr += QString::number(po.base);
+ mstr += "</sub>";
+ } else {
+ mstr += TEXT_TAGS_SMALL "<sup>";
+ mstr += QString::number(po.base);
+ mstr += "</sup>" TEXT_TAGS_SMALL_END;
+ }
+ }
+ STR_MARKUP_END(mstr);
+ break;
+ }
+ case STRUCT_SYMBOLIC: {
+ result_parts.push_back(m);
+ mstr = "<a name=\"";
+ mstr += QString::number(result_parts.size());
+ mstr += "\">";
+ STR_MARKUP_BEGIN_CURSIVE(mstr);
+ mstr += m.symbol().c_str();
+ STR_MARKUP_END_CURSIVE(mstr);
+ mstr += "</a>";
+ mstr += "<a name=\"";
+ mstr += QString::number(result_parts.size());
+ mstr += "\"></a>";
+ break;
+ }
+ case STRUCT_ADDITION: {
+
+ ips_n.depth++;
+
+ vector<QString> terms;
+ vector<bool> do_space;
+ for(size_t i = 0; i < m.size(); i++) {
+ if(m[i].type() == STRUCT_NEGATE && i > 0) {
+ 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);
+ terms.push_back(draw_structure(m[i][0], font, cg, po, ips_n));
+ } else {
+ ips_n.wrap = m[i].needsParenthesis(po, ips_n, m, i + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
+ terms.push_back(draw_structure(m[i], font, cg, po, ips_n));
+ }
+ do_space.push_back(!terms[i].endsWith("valign=\"middle\">"));
+ }
+ for(size_t i = 0; i < terms.size(); i++) {
+ if(i > 0) {
+ if(do_space[i - 1]) STR_MARKUP_ADD(mstr, " ");
+ if(m[i].type() == STRUCT_NEGATE) {
+ 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))) {
+ STR_MARKUP_ADD(mstr, SIGN_MINUS);
+ } else {
+ STR_MARKUP_ADD(mstr, "-");
+ }
+ } else {
+ STR_MARKUP_ADD(mstr, "+");
+ }
+ if(do_space[i]) STR_MARKUP_ADD(mstr, " ");
+ }
+ mstr += terms[i];
+ }
+ break;
+ }
+ case STRUCT_NEGATE: {
+
+ ips_n.depth++;
+
+ ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
+ 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))) {
+ STR_MARKUP_ADD(mstr, SIGN_MINUS);
+ } else {
+ STR_MARKUP_ADD(mstr, "-");
+ }
+ mstr += draw_structure(m[0], font, cg, po, ips_n);
+ break;
+ }
+ case STRUCT_MULTIPLICATION: {
+
+ ips_n.depth++;
+
+ QString mul_str;
+ 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))) {
+ STR_MARKUP_ADD(mul_str, SIGN_MULTIDOT);
+ } 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))) {
+ STR_MARKUP_ADD(mul_str, SIGN_MULTIBULLET);
+ } 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))) {
+ STR_MARKUP_ADD(mul_str, SIGN_SMALLCIRCLE);
+ } 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))) {
+ STR_MARKUP_ADD(mul_str, SIGN_MULTIPLICATION);
+ } else {
+ STR_MARKUP_ADD(mul_str, "*");
+ }
+
+ bool par_prev = false;
+ vector<int> nm;
+ vector<QString> terms;
+ vector<bool> do_space;
+ for(size_t i = 0; i < m.size(); i++) {
+ ips_n.wrap = m[i].needsParenthesis(po, ips_n, m, i + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
+ terms.push_back(draw_structure(m[i], font, cg, po, ips_n));
+ if(!po.short_multiplication && i > 0) {
+ nm.push_back(-1);
+ } else if(i > 0) {
+ 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));
+ } else {
+ nm.push_back(-1);
+ }
+ do_space.push_back(!terms[i].endsWith("valign=\"middle\">"));
+ par_prev = ips_n.wrap;
+ }
+ for(size_t i = 0; i < terms.size(); i++) {
+ if(!po.short_multiplication && i > 0) {
+ if(do_space[i - 1]) STR_MARKUP_ADD(mstr, " ");
+ mstr += mul_str;
+ if(do_space[i]) STR_MARKUP_ADD(mstr, " ");
+ } else if(i > 0) {
+ switch(nm[i]) {
+ case MULTIPLICATION_SIGN_SPACE: {
+ if(do_space[i - 1] && do_space[i]) STR_MARKUP_ADD(mstr, " ");
+ break;
+ }
+ case MULTIPLICATION_SIGN_OPERATOR: {
+ if(do_space[i - 1]) STR_MARKUP_ADD(mstr, " ");
+ mstr += mul_str;
+ if(do_space[i]) STR_MARKUP_ADD(mstr, " ");
+ break;
+ }
+ case MULTIPLICATION_SIGN_OPERATOR_SHORT: {
+ mstr += mul_str;
+ break;
+ }
+ }
+ }
+ mstr += terms[i];
+ }
+ break;
+ }
+ case STRUCT_INVERSE: {}
+ case STRUCT_DIVISION: {
+
+ ips_n.depth++;
+ ips_n.division_depth++;
+
+ bool flat = ips.division_depth > 0 || ips.power_depth > 0;
+ if(!flat && po.place_units_separately) {
+ flat = true;
+ size_t i = 0;
+ if(m.isDivision()) {
+ i = 1;
+ }
+ if(m[i].isMultiplication()) {
+ for(size_t i2 = 0; i2 < m[i].size(); i2++) {
+ if(!m[i][i2].isUnit_exp()) {
+ flat = false;
+ break;
+ }
+ }
+ } else if(!m[i].isUnit_exp()) {
+ flat = false;
+ }
+ if(flat) {
+ ips_n.division_depth--;
+ }
+ }
+ QString num_str, den_str;
+ if(m.type() == STRUCT_DIVISION) {
+ 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);
+ num_str = draw_structure(m[0], font, cg, po, ips_n);
+ } else {
+ MathStructure onestruct(1, 1);
+ ips_n.wrap = false;
+ num_str = draw_structure(onestruct, font, cg, po, ips_n);
+ }
+ if(m.type() == STRUCT_DIVISION) {
+ ips_n.wrap = m[1].needsParenthesis(po, ips_n, m, 2, flat, ips.power_depth > 0);
+ den_str = draw_structure(m[1], font, cg, po, ips_n);
+ } else {
+ ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 2, flat, ips.power_depth > 0);
+ den_str = draw_structure(m[0], font, cg, po, ips_n);
+ }
+
+ if(flat) {
+ QString div_str;
+ 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))) {
+ STR_MARKUP_ADD(div_str, " " SIGN_DIVISION " ");
+ } 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))) {
+ STR_MARKUP_ADD(div_str, " " SIGN_DIVISION_SLASH " ");
+ } else {
+ STR_MARKUP_ADD(div_str, " / ");
+ }
+ mstr = num_str;
+ mstr += div_str;
+ mstr += den_str;
+ } else {
+
+ int den_w, num_w, w = 0, h = 0;
+
+ num_str.prepend(TEXT_TAGS);
+ num_str += TEXT_TAGS_END;
+ den_str.prepend(TEXT_TAGS);
+ den_str += TEXT_TAGS_END;
+
+ QSimpleRichText text_r(num_str, font); text_r.setWidth(10000);
+ num_w = text_r.widthUsed();
+ QSimpleRichText text_rn(den_str, font); text_rn.setWidth(10000);
+ den_w = text_rn.widthUsed();
+
+ w = den_w;
+ if(num_w > w) w = num_w;
+ w += 2;
+
+ QSimpleRichText textsmall("<font size=\"1\">X</font>", font);
+ h = (int) (textsmall.height() / 1.5);
+ h += h % 2;
+
+ string filename = getLocalDir();
+ if(saved_divisionline_height != h) {
+
+ QPixmap *pixmap = new QPixmap(10, h);
+ pixmap->fill(cg.background());
+ QPainter p(pixmap);
+ QPen ppen = p.pen();
+ ppen.setColor(cg.foreground());
+ p.setPen(ppen);
+ p.drawLine(0, h / 2, 10, h / 2);
+ p.drawLine(0, h / 2 + 1, 10, h / 2 + 1);
+ p.flush();
+ p.end();
+
+ pixmap->setMask(pixmap->createHeuristicMask());
+ mkdir(filename.c_str(), S_IRWXU);
+ filename += "tmp/";
+ mkdir(filename.c_str(), S_IRWXU);
+ filename += "divline.png";
+ pixmap->save(filename.c_str(), "PNG", 100);
+
+ delete pixmap;
+
+ saved_divisionline_height = h;
+
+ } else {
+
+ filename += "tmp/divline.png";
+
+ }
+
+ mstr = TEXT_TAGS_END;
+ mstr = "</td><td width=1 align=\"center\" valign=\"middle\">";
+ mstr += num_str;
+ mstr += "<br><font size=1><img align=\"middle\" width=";
+ mstr += QString::number(w);
+ mstr += " height=";
+ mstr += QString::number(h);
+ mstr += " src=\"";
+ mstr += filename.c_str();
+ mstr += "\"><br></font>";
+ mstr += den_str;
+ mstr += "</td><td width=1 align=\"center\" valign=\"middle\">";
+ mstr += TEXT_TAGS;
+
+ }
+ break;
+ }
+ case STRUCT_POWER: {
+
+ ips_n.depth++;
+
+ ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
+
+ ips_n.division_depth++;
+ mstr += draw_structure(m[0], font, cg, po, ips_n);
+ ips_n.division_depth--;
+
+ ips_n.power_depth++;
+ ips_n.wrap = m[1].needsParenthesis(po, ips_n, m, 2, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
+
+ PrintOptions po2 = po;
+ po2.show_ending_zeroes = false;
+ if(ips.power_depth > 0) {
+ mstr += TEXT_TAGS "<sup>" "^" "</sup>" TEXT_TAGS_END;
+ mstr += draw_structure(m[1], font, cg, po2, ips_n);
+ } else {
+ mstr += draw_structure(m[1], font, cg, po2, ips_n);
+ }
+
+ break;
+ }
+ case STRUCT_LOGICAL_AND: {
+ 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]) {
+
+ ips_n.depth++;
+
+ bool do_space = true;
+ QString tstr;
+ 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);
+ tstr = draw_structure(m[0][1], font, cg, po, ips_n);
+ do_space = !tstr.endsWith("valign=\"middle\">");
+ mstr += tstr;
+ STR_MARKUP_BEGIN(mstr);
+ if(do_space) mstr += " ";
+ switch(m[0].comparisonType()) {
+ case COMPARISON_LESS: {
+ mstr += "&gt;";
+ break;
+ }
+ case COMPARISON_GREATER: {
+ mstr += "&lt;";
+ break;
+ }
+ case COMPARISON_EQUALS_LESS: {
+ 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))) {
+ mstr += SIGN_GREATER_OR_EQUAL;
+ } else {
+ mstr += "&gt;=";
+ }
+ break;
+ }
+ case COMPARISON_EQUALS_GREATER: {
+ 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))) {
+ mstr += SIGN_LESS_OR_EQUAL;
+ } else {
+ mstr += "&lt;=";
+ }
+ break;
+ }
+ default: {}
+ }
+
+ 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);
+ tstr = draw_structure(m[0][0], font, cg, po, ips_n);
+ do_space = !tstr.endsWith("valign=\"middle\">");
+ if(do_space) mstr += " ";
+ STR_MARKUP_END(mstr);
+ mstr += tstr;
+ STR_MARKUP_BEGIN(mstr);
+ if(do_space) mstr += " ";
+
+ switch(m[1].comparisonType()) {
+ case COMPARISON_GREATER: {
+ mstr += "&gt;";
+ break;
+ }
+ case COMPARISON_LESS: {
+ mstr += "&lt;";
+ break;
+ }
+ case COMPARISON_EQUALS_GREATER: {
+ 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))) {
+ mstr += SIGN_GREATER_OR_EQUAL;
+ } else {
+ mstr += "&gt;=";
+ }
+ break;
+ }
+ case COMPARISON_EQUALS_LESS: {
+ 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))) {
+ mstr += SIGN_LESS_OR_EQUAL;
+ } else {
+ mstr += "&lt;=";
+ }
+ break;
+ }
+ default: {}
+ }
+
+ 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);
+ tstr = draw_structure(m[1][1], font, cg, po, ips_n);
+ do_space = !tstr.endsWith("valign=\"middle\">");
+ if(do_space) mstr += " ";
+ STR_MARKUP_END(mstr);
+ mstr += tstr;
+
+ break;
+ }
+ }
+ case STRUCT_COMPARISON: {}
+ case STRUCT_LOGICAL_XOR: {}
+ case STRUCT_LOGICAL_OR: {}
+ case STRUCT_BITWISE_AND: {}
+ case STRUCT_BITWISE_XOR: {}
+ case STRUCT_BITWISE_OR: {
+
+ ips_n.depth++;
+
+ QString str;
+ if(m.type() == STRUCT_COMPARISON) {
+ switch(m.comparisonType()) {
+ case COMPARISON_EQUALS: {
+ break;
+ }
+ case COMPARISON_NOT_EQUALS: {
+ 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))) {
+ str += SIGN_NOT_EQUAL;
+ } else {
+ str += "!=";
+ }
+ break;
+ }
+ case COMPARISON_GREATER: {
+ str += "&gt;";
+ break;
+ }
+ case COMPARISON_LESS: {
+ str += "&lt;";
+ break;
+ }
+ case COMPARISON_EQUALS_GREATER: {
+ 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))) {
+ str += SIGN_GREATER_OR_EQUAL;
+ } else {
+ str += "&gt;=";
+ }
+ break;
+ }
+ case COMPARISON_EQUALS_LESS: {
+ 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))) {
+ str += SIGN_LESS_OR_EQUAL;
+ } else {
+ str += "&lt;=";
+ }
+ break;
+ }
+ }
+ } else if(m.type() == STRUCT_LOGICAL_AND) {
+ str += "<a name=\"+Logical AND\">";
+ if(po.spell_out_logical_operators) str += i18n("and");
+ else str += "&amp;&amp;";
+ str += "</a>";
+ } else if(m.type() == STRUCT_LOGICAL_OR) {
+ str += "<a name=\"+Logical inclusive OR\">";
+ if(po.spell_out_logical_operators) str += i18n("or");
+ else str += "||";
+ str += "</a>";
+ } else if(m.type() == STRUCT_LOGICAL_XOR) {
+ str += "<a name=\"+Logical exclusive OR\">XOR</a>";
+ } else if(m.type() == STRUCT_BITWISE_AND) {
+ str += "<a name=\"+Bitwise AND\">&amp;</a>";
+ } else if(m.type() == STRUCT_BITWISE_OR) {
+ str += "<a name=\"+Bitwise inclusive OR\">|</a>";
+ } else if(m.type() == STRUCT_BITWISE_XOR) {
+ str += "<a name=\"+Bitwise exclusive XOR\">XOR</a>";
+ }
+
+ bool do_space = true, do_space_prev = true;
+ QString tstr;
+ for(size_t i = 0; i < m.size(); i++) {
+ do_space_prev = do_space;
+ ips_n.wrap = m[i].needsParenthesis(po, ips_n, m, i + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
+ tstr = draw_structure(m[i], font, cg, po, ips_n);
+ do_space = !tstr.endsWith("valign=\"middle\">");
+ if(i > 0) {
+ STR_MARKUP_BEGIN(mstr);
+ if(do_space_prev) mstr += " ";
+ if(m.isComparison() && m.comparisonType() == COMPARISON_EQUALS) {
+ 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))) {
+ mstr += SIGN_ALMOST_EQUAL;
+ } else {
+ mstr += "=";
+ }
+ } else {
+ mstr += str;
+ }
+ if(do_space) mstr += " ";
+ STR_MARKUP_END(mstr);
+ }
+ mstr += tstr;
+ }
+ break;
+ }
+ case STRUCT_BITWISE_NOT: {
+
+ ips_n.depth++;
+
+ STR_MARKUP_BEGIN(mstr);
+
+ mstr += "<a name=\"+Bitwise NOT\">~</a>";
+
+ ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
+ mstr += draw_structure(m[0], font, cg, po, ips_n);
+
+ STR_MARKUP_END(mstr);
+
+ break;
+ }
+ case STRUCT_LOGICAL_NOT: {
+
+ ips_n.depth++;
+
+ STR_MARKUP_BEGIN(mstr);
+
+ mstr += "<a name=\"+Logical NOT\">!</a>";
+
+ ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
+ mstr += draw_structure(m[0], font, cg, po, ips_n);
+
+ STR_MARKUP_END(mstr);
+
+ break;
+ }
+ case STRUCT_VECTOR: {
+
+ ips_n.depth++;
+
+ bool is_matrix = m.isMatrix();
+ if(!in_matrix) {
+ result_parts.push_back(m);
+ mstr = "<a name=\"";
+ mstr += QString::number(result_parts.size());
+ mstr += "\">";
+ }
+
+ if(m.size() == 0) {
+ STR_MARKUP_ADD(mstr, "( ");
+ } else {
+ STR_MARKUP_ADD(mstr, "(");
+ }
+ for(size_t index = 0; index < m.size(); index++) {
+ if(index > 0) {
+ STR_MARKUP_BEGIN(mstr);
+ mstr += CALCULATOR->getComma().c_str();
+ mstr += " ";
+ STR_MARKUP_END(mstr);
+ }
+ ips_n.wrap = m[index].needsParenthesis(po, ips_n, m, index + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0);
+ mstr += draw_structure(m[index], font, cg, po, ips_n, is_matrix);
+ }
+ STR_MARKUP_ADD(mstr, ")");
+ if(!in_matrix) mstr += "</a>";
+ break;
+ }
+ case STRUCT_UNIT: {
+
+ result_parts.push_back(m);
+ mstr = "<a name=\"";
+ mstr += QString::number(result_parts.size());
+ mstr += "\">";
+
+ STR_MARKUP_BEGIN(mstr);
+
+ QString str;
+ 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);
+ if(m.prefix()) {
+ 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();
+ }
+ if(ename->suffix && ename->name.length() > 1) {
+ size_t i = ename->name.rfind('_');
+ bool b = i == string::npos || i == ename->name.length() - 1 || i == 0;
+ size_t i2 = 1;
+ if(b) {
+ if(is_in(NUMBERS, ename->name[ename->name.length() - 1])) {
+ while(ename->name.length() > i2 + 1 && is_in(NUMBERS, ename->name[ename->name.length() - 1 - i2])) {
+ i2++;
+ }
+ }
+ str += ename->name.substr(0, ename->name.length() - i2).c_str();
+ } else {
+ str += ename->name.substr(0, i).c_str();
+ }
+ if(ips.power_depth == 0) str += "<sub>";
+ else str += TEXT_TAGS_SMALL "<sup>";
+ if(b) str += ename->name.substr(ename->name.length() - i2, i2).c_str();
+ else str += ename->name.substr(i + 1, ename->name.length() - (i + 1)).c_str();
+ if(ips.power_depth == 0) str += "</sub>";
+ else str += "</sup>" TEXT_TAGS_SMALL_END;
+ } else {
+ str += ename->name.c_str();
+ }
+ str.replace("_", " ");
+ mstr += str;
+
+ STR_MARKUP_END(mstr);
+ mstr += "</a>";
+ mstr += "<a name=\"";
+ mstr += QString::number(result_parts.size());
+ mstr += "\"></a>";
+
+ break;
+ }
+ case STRUCT_VARIABLE: {
+
+ result_parts.push_back(m);
+ mstr = "<a name=\"";
+ mstr += QString::number(result_parts.size());
+ mstr += "\">";
+ if(m.variable() == CALCULATOR->v_i) {
+ STR_MARKUP_BEGIN(mstr);
+ } else {
+ STR_MARKUP_BEGIN_CURSIVE(mstr);
+ }
+
+ QString str;
+ 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);
+ if(ename->suffix && ename->name.length() > 1) {
+ size_t i = ename->name.rfind('_');
+ bool b = i == string::npos || i == ename->name.length() - 1 || i == 0;
+ size_t i2 = 1;
+ if(b) {
+ if(is_in(NUMBERS, ename->name[ename->name.length() - 1])) {
+ while(ename->name.length() > i2 + 1 && is_in(NUMBERS, ename->name[ename->name.length() - 1 - i2])) {
+ i2++;
+ }
+ }
+ str += ename->name.substr(0, ename->name.length() - i2).c_str();
+ } else {
+ str += ename->name.substr(0, i).c_str();
+ }
+ if(ips.power_depth == 0) str += "<sub>";
+ else str += TEXT_TAGS_SMALL "<sup>";
+ if(b) str += ename->name.substr(ename->name.length() - i2, i2).c_str();
+ else str += ename->name.substr(i + 1, ename->name.length() - (i + 1)).c_str();
+ if(ips.power_depth == 0) str += "</sub>";
+ else str += "</sup>" TEXT_TAGS_SMALL_END;
+ } else {
+ str += ename->name.c_str();
+ }
+ str.replace("_", " ");
+ mstr += str;
+
+ if(m.variable() == CALCULATOR->v_i) {
+ STR_MARKUP_END(mstr);
+ } else {
+ STR_MARKUP_END_CURSIVE(mstr);
+ }
+ mstr += "</a>";
+ /*result_parts.push_back(m);
+ mstr += "<a name=\"";
+ mstr += QString::number(result_parts.size());
+ mstr += "\"></a>";*/
+ break;
+ }
+ case STRUCT_FUNCTION: {
+
+ ips_n.depth++;
+
+ result_parts.push_back(m);
+ mstr = "<a name=\"";
+ mstr += QString::number(result_parts.size());
+ mstr += "\">";
+
+ STR_MARKUP_BEGIN(mstr);
+
+ QString str;
+ 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);
+ if(ename->suffix && ename->name.length() > 1) {
+ size_t i = ename->name.rfind('_');
+ bool b = i == string::npos || i == ename->name.length() - 1 || i == 0;
+ size_t i2 = 1;
+ if(b) {
+ if(is_in(NUMBERS, ename->name[ename->name.length() - 1])) {
+ while(ename->name.length() > i2 + 1 && is_in(NUMBERS, ename->name[ename->name.length() - 1 - i2])) {
+ i2++;
+ }
+ }
+ str += ename->name.substr(0, ename->name.length() - i2).c_str();
+ } else {
+ str += ename->name.substr(0, i).c_str();
+ }
+ if(ips.power_depth == 0) str += "<sub>";
+ else str += TEXT_TAGS_SMALL "<sup>";
+ if(b) str += ename->name.substr(ename->name.length() - i2, i2).c_str();
+ else str += ename->name.substr(i + 1, ename->name.length() - (i + 1)).c_str();
+ if(ips.power_depth == 0) str += "</sub>";
+ else str += "</sup>" TEXT_TAGS_SMALL_END;
+ } else {
+ str += ename->name.c_str();
+ }
+ str.replace("_", " ");
+ mstr += str;
+
+ mstr += "(";
+ STR_MARKUP_END(mstr);
+ mstr += "</a>";
+
+ for(size_t index = 0; index < m.size(); index++) {
+ if(index > 0) {
+ STR_MARKUP_BEGIN(mstr);
+ mstr += po.comma().c_str();
+ mstr += " ";
+ STR_MARKUP_END(mstr);
+ }
+ mstr += draw_structure(m[index], font, cg, po, ips_n);
+ }
+ STR_MARKUP_ADD(mstr, ")");
+
+ break;
+ }
+ case STRUCT_UNDEFINED: {
+ STR_MARKUP_ADD(mstr, i18n("undefined"));
+ break;
+ }
+ default: {
+ }
+ }
+ if(ips.wrap) {
+ STR_MARKUP_PREPEND(mstr, "(");
+ STR_MARKUP_ADD(mstr, ")");
+ }
+ 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)))))) {
+ QString equals_str;
+ if(*po.is_approximate || m.isApproximate()) {
+ 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))) {
+ equals_str = SIGN_ALMOST_EQUAL " ";
+ } else {
+ equals_str += i18n("approx.");
+ equals_str += " ";
+ }
+ } else {
+ equals_str = "= ";
+ }
+ mstr.prepend(equals_str);
+ }
+ if(ips.depth == 0) {
+ mstr.prepend(TEXT_TAGS);
+ mstr += TEXT_TAGS_END;
+ }
+
+ return mstr;
+
+}
+
+#define STATUS_SPACE if(b) str += " "; else b = true;
+
+void KQalculate::update_status_text() {
+
+ QString str;
+ bool b = false;
+
+ if(evalops.approximation == APPROXIMATION_EXACT) {
+ STATUS_SPACE
+ str += i18n("EXACT");
+ } else if(evalops.approximation == APPROXIMATION_APPROXIMATE) {
+ STATUS_SPACE
+ str += i18n("APPROX");
+ }
+ if(evalops.parse_options.rpn) {
+ STATUS_SPACE
+ str += i18n("RPN");
+ }
+ switch(evalops.parse_options.base) {
+ case BASE_DECIMAL: {
+ break;
+ }
+ case BASE_BINARY: {
+ STATUS_SPACE
+ str += i18n("BIN");
+ break;
+ }
+ case BASE_OCTAL: {
+ STATUS_SPACE
+ str += i18n("OCT");
+ break;
+ }
+ case BASE_HEXADECIMAL: {
+ STATUS_SPACE
+ str += i18n("HEX");
+ break;
+ }
+ case BASE_ROMAN_NUMERALS: {
+ STATUS_SPACE
+ str += i18n("ROMAN");
+ break;
+ }
+ default: {
+ STATUS_SPACE
+ str += QString::number(evalops.parse_options.base);
+ break;
+ }
+ }
+ switch (evalops.parse_options.angle_unit) {
+ case ANGLE_UNIT_DEGREES: {
+ STATUS_SPACE
+ str += i18n("DEG");
+ break;
+ }
+ case ANGLE_UNIT_RADIANS: {
+ STATUS_SPACE
+ str += i18n("RAD");
+ break;
+ }
+ case ANGLE_UNIT_GRADIANS: {
+ STATUS_SPACE
+ str += i18n("GRA");
+ break;
+ }
+ default: {}
+ }
+ if(evalops.parse_options.read_precision != DONT_READ_PRECISION) {
+ STATUS_SPACE
+ str += i18n("PREC");
+ }
+ if(!evalops.parse_options.functions_enabled) {
+ STATUS_SPACE
+ str += "<s>";
+ str += i18n("FUNC");
+ str += "</s>";
+ }
+ if(!evalops.parse_options.units_enabled) {
+ STATUS_SPACE
+ str += "<s>";
+ str += i18n("UNIT");
+ str += "</s>";
+ }
+ if(!evalops.parse_options.variables_enabled) {
+ STATUS_SPACE
+ str += "<s>";
+ str += i18n("VAR");
+ str += "</s>";
+ }
+ if(!evalops.allow_infinite) {
+ STATUS_SPACE
+ str += "<s>";
+ str += i18n("INF");
+ str += "</s>";
+ }
+ if(!evalops.allow_complex) {
+ STATUS_SPACE
+ str += "<s>";
+ str += i18n("CPLX");
+ str += "</s>";
+ }
+ str = str.stripWhiteSpace();
+ if(b) str += "&nbsp;";
+ else str += "&nbsp;&nbsp;";
+
+ if(str != statusLabel_r->text()) {
+ statusLabel_r->setText(str);
+ qApp->processEvents();
+ displayParseStatus();
+ }
+
+}
+
+
+void on_abort_display() {
+ pthread_cancel(view_thread);
+ CALCULATOR->restoreState();
+ CALCULATOR->clearBuffers();
+ b_busy = false;
+ pthread_create(&view_thread, &view_thread_attr, view_proc, view_pipe_r);
+}
+
+void *view_proc(void *pipe) {
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+ FILE *view_pipe = (FILE*) pipe;
+
+ while(true) {
+
+ bool *do_wrap;
+ void *x = NULL;
+ fread(&x, sizeof(void*), 1, view_pipe);
+ KQalculate *win = (KQalculate*) x;
+ fread(&x, sizeof(void*), 1, view_pipe);
+ MathStructure m(*((MathStructure*) x));
+ fread(&x, sizeof(void*), 1, view_pipe);
+ MathStructure *mm = (MathStructure*) x;
+ fread(&do_wrap, sizeof(bool*), 1, view_pipe);
+ fread(&x, sizeof(void*), 1, view_pipe);
+ printops.can_display_unicode_string_arg = (void*) win->historyBrowser;
+ if(x) {
+ PrintOptions po;
+ po.preserve_format = true;
+ po.show_ending_zeroes = true;
+ po.lower_case_e = printops.lower_case_e;
+ po.lower_case_numbers = printops.lower_case_numbers;
+ po.base_display = printops.base_display;
+ po.abbreviate_names = false;
+ po.use_unicode_signs = printops.use_unicode_signs;
+ po.multiplication_sign = printops.multiplication_sign;
+ po.division_sign = printops.division_sign;
+ po.short_multiplication = false;
+ po.excessive_parenthesis = true;
+ po.improve_division_multipliers = false;
+ po.can_display_unicode_string_function = &can_display_unicode_string_function;
+ po.can_display_unicode_string_arg = (void*) win->statusLabel_l;
+ po.spell_out_logical_operators = printops.spell_out_logical_operators;
+ po.restrict_to_parent_precision = false;
+ MathStructure mp(*((MathStructure*) x));
+ fread(&po.is_approximate, sizeof(bool*), 1, view_pipe);
+ mp.format(po);
+ parsed_text = mp.print(po).c_str();
+ fread(&x, sizeof(void*), 1, view_pipe);
+ mp.set(*((MathStructure*) x));
+ if(!mp.isUndefined()) {
+ mp.format(po);
+ parsed_text += CALCULATOR->localToString().c_str();
+ parsed_text += mp.print(po).c_str();
+ }
+ }
+ printops.allow_non_usable = false;
+ if(mm && m.isMatrix()) {
+ mm->set(m);
+ MathStructure mm2(m);
+ string mstr;
+ int c = mm->columns(), r = mm->rows();
+ for(int index_r = 0; index_r < r; index_r++) {
+ for(int index_c = 0; index_c < c; index_c++) {
+ mm->getElement(index_r + 1, index_c + 1)->set(i18n("aborted").ascii());
+ }
+ }
+ for(int index_r = 0; index_r < r; index_r++) {
+ for(int index_c = 0; index_c < c; index_c++) {
+ mm2.getElement(index_r + 1, index_c + 1)->format(printops);
+ mstr = mm2.getElement(index_r + 1, index_c + 1)->print(printops);
+ mm->getElement(index_r + 1, index_c + 1)->set(mstr);
+ }
+ }
+ }
+ m.format(printops);
+ result_history_text = m.print(printops).c_str();
+ printops.can_display_unicode_string_arg = NULL;
+ /*if(result_history_text.length() > 5000) {
+ result_text = i18n("result is too long\nsee history");
+ *printops.is_approximate = false;
+ } else */
+ if(mm && result_text == i18n("aborted")) {
+ result_text = i18n("calculation was aborted");
+ *printops.is_approximate = false;
+ } else if(mm) {
+ printops.allow_non_usable = true;
+ printops.can_display_unicode_string_arg = (void*) win->resultLabel;
+ QFont font(win->resultLabel->font());
+ result_text = draw_structure(m, font, win->resultLabel->colorGroup(), printops);
+ if(result_text.find("</td>") >= 0) {
+ result_text.prepend("<div align=\"right\"><table width=1 cellspacing=0 cellpadding=0 border=0><tr><td width=1 align=\"center\" valign=\"middle\">");
+ result_text += "</td></tr></table></div>";
+ *do_wrap = false;
+ } else {
+ result_text.prepend("<div align=\"right\"><font size=2>&nbsp;<br></font>");
+ result_text += "</div>";
+ *do_wrap = true;
+ }
+ printops.can_display_unicode_string_arg = NULL;
+ printops.allow_non_usable = false;
+ }
+ b_busy = false;
+ }
+ return NULL;
+}
+
+void KQalculate::clearresult() {
+ resultLabel->setRightMargin(10);
+ resultLabel->setText("<font size=6> </font>");
+ parsed_text = "";
+ result_parts.clear();
+}
+
+void reduceDivLineSize(QalculateResultDisplay *resultLabel) {
+
+ QString str = result_text;
+ QColorGroup cg = resultLabel->colorGroup();
+ int rt_i = 0;
+ while(true) {
+
+ int i2 = str.find("</td><td width=1 align=\"center\" valign=\"middle\">", 0);
+ if(i2 < 0) break;
+ str.remove(0, i2 + 48);
+ rt_i += i2 + 48;
+ i2 = str.find("<br>", 0);
+ if(i2 < 0) break;
+ int width_i = rt_i + i2 + 43;
+ QString num_str = str;
+ num_str.truncate(i2);
+
+ i2 = str.find("<br>", i2 + 4);
+ if(i2 < 0) break;
+ str.remove(0, i2 + 11);
+ rt_i += i2 + 11;
+ i2 = str.find("</td><td width=1 align=\"center\" valign=\"middle\">", 0);
+ if(i2 < 0) break;
+ QString den_str = str;
+ den_str.truncate(i2);
+ str.remove(0, i2 + 48);
+ rt_i += i2 + 48;
+
+ int den_w, num_w, w = 0, h = 0;
+ QSimpleRichText text_r(num_str, resultLabel->font()); text_r.setWidth(10000);
+ num_w = text_r.widthUsed();
+ QSimpleRichText text_rn(den_str, resultLabel->font()); text_rn.setWidth(10000);
+ den_w = text_rn.widthUsed();
+
+ w = den_w;
+ if(num_w > w) w = num_w;
+ w += 2;
+
+ QSimpleRichText textsmall("<font size=\"1\">X</font>", resultLabel->font());
+ h = (int) (textsmall.height() / 1.5);
+ h += h % 2;
+
+ string filename = getLocalDir();
+ if(saved_divisionline_height != h) {
+
+ QPixmap *pixmap = new QPixmap(10, h);
+ pixmap->fill(cg.background());
+ QPainter p(pixmap);
+ QPen ppen = p.pen();
+ ppen.setColor(cg.foreground());
+ p.setPen(ppen);
+ p.drawLine(0, h / 2, 10, h / 2);
+ p.drawLine(0, h / 2 + 1, 10, h / 2 + 1);
+ p.flush();
+ p.end();
+
+ pixmap->setMask(pixmap->createHeuristicMask());
+ mkdir(filename.c_str(), S_IRWXU);
+ filename += "tmp/";
+ mkdir(filename.c_str(), S_IRWXU);
+ filename += "divline.png";
+ pixmap->save(filename.c_str(), "PNG", 100);
+
+ delete pixmap;
+
+ saved_divisionline_height = h;
+
+ } else {
+
+ filename += "tmp/divline.png";
+
+ }
+
+ int height_i = result_text.find(" height=", width_i);
+ if(height_i < 0) break;
+ num_str = QString::number(w);
+ result_text.replace(width_i, height_i - width_i, num_str);
+ int i_diff = num_str.length() - (height_i - width_i);
+ rt_i += i_diff;
+ height_i += i_diff;
+ height_i += 8;
+ int height_i_end = result_text.find(" src=", height_i);
+ if(height_i_end < 0) break;
+ num_str = QString::number(h);
+ result_text.replace(height_i, height_i_end - height_i, num_str);
+ i_diff = num_str.length() - (height_i_end - height_i);
+ rt_i += i_diff;
+
+ }
+
+}
+
+Prefix *set_result_prefix;
+bool set_result_update_history;
+bool set_result_update_parse;
+bool set_result_force;
+QString set_result_transformation;
+size_t set_result_stack_index;
+bool set_result_register_moved;
+
+void KQalculate::setResult(Prefix *prefix, bool update_history, bool update_parse, bool force, QString transformation, size_t stack_index, bool register_moved) {
+ if(expression_has_changed && !rpn_mode) {
+ if(!force) return;
+ execute_expression();
+ if(!prefix) return;
+ }
+ set_result_prefix = prefix;
+ set_result_update_history = update_history;
+ set_result_update_parse = update_parse;
+ set_result_force = force;
+ set_result_transformation = transformation;
+ set_result_stack_index = stack_index;
+ set_result_register_moved = register_moved;
+ QTimer::singleShot(0, this, SLOT(setResult2()));
+}
+void KQalculate::setResult2() {
+ if(block_result_update) return;
+ Prefix *prefix = set_result_prefix;
+ bool update_history = set_result_update_history;
+ bool update_parse = set_result_update_parse;
+ bool force = set_result_force;
+ bool register_moved = set_result_register_moved;
+ QString transformation = set_result_transformation;
+ size_t stack_index = set_result_stack_index;
+
+ if(!rpn_mode) stack_index = 0;
+ if(stack_index != 0) {
+ update_history = true;
+ update_parse = false;
+ }
+ if(register_moved) {
+ update_history = true;
+ update_parse = false;
+ }
+
+ error_timer->stop();
+ b_busy = true;
+
+ uint history_index = 0;
+ int inhistory_index = 0;
+ if(update_history) {
+ if(update_parse || register_moved) {
+ QString text;
+ if(register_moved) {
+ text = i18n("RPN Register Moved");
+ inhistory.insert(inhistory.begin(), QString::null);
+ inhistory_type.insert(inhistory_type.begin(), QALCULATE_HISTORY_REGISTER_MOVED);
+ inhistory_id.insert(inhistory_id.begin(), inhistory_current_id);
+ inhistory_current_id++;
+ inhistory_index++;
+ } else {
+ QString text2 = result_history_text;
+ text2.replace("&", "&amp;");
+ text2.replace(">", "&gt;");
+ text2.replace("<", "&lt;");
+ text = "<a name=\"";
+ text += QString::number(inhistory_current_id);
+ text += "\">";
+ text += text2;
+ text += "</a>";
+ inhistory.insert(inhistory.begin(), text2);
+ inhistory_type.insert(inhistory_type.begin(), QALCULATE_HISTORY_EXPRESSION);
+ inhistory_id.insert(inhistory_id.begin(), inhistory_current_id);
+ inhistory_index++;
+ inhistory_current_id++;
+ }
+ int l = text.length();
+ text += " <br><hr>";
+ text += historyBrowser->text();
+ history_index = l + 1;
+ historyBrowser->setText(text);
+ } else if(initial_result_index == 0) {
+ b_busy = false;
+ error_timer->start(100);
+ return;
+ } else {
+ inhistory_index = initial_inhistory_index;
+ if(!transformation.isEmpty()) {
+ transformation.replace("&", "&amp;");
+ transformation.replace(">", "&gt;");
+ transformation.replace("<", "&lt;");
+ inhistory.insert(inhistory.begin(), transformation);
+ inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_TRANSFORMATION);
+ inhistory_id.insert(inhistory_id.begin() + inhistory_index, inhistory_current_id);
+ inhistory_current_id++;
+ inhistory_index++;
+ transformation.insert(0, "<i>");
+ transformation += ": </i><br>";
+ QString text = historyBrowser->text();
+ text.insert(initial_result_index, transformation);
+ historyBrowser->setText(text);
+ initial_result_index += transformation.length() - 4;
+ }
+ history_index = initial_result_index;
+ }
+ result_history_text = "?";
+ }
+ if(update_parse) {
+ parsed_text = i18n("aborted");
+ }
+
+ if(stack_index == 0) {
+ resultLabel->setRightMargin(10);
+ resultLabel->setText("<font size=6> </font>");
+ result_parts.clear();
+ result_text = i18n("result processing was aborted");
+ }
+
+ *printops.is_approximate = false;
+
+ printops.prefix = prefix;
+
+ CALCULATOR->saveState();
+
+ bool parsed_approx = false;
+ bool do_wrap = true;
+ KQalculate *win = this;
+ fwrite(&win, sizeof(void*), 1, view_pipe_w);
+ if(stack_index == 0) {
+ fwrite(&mstruct, sizeof(void*), 1, view_pipe_w);
+ matrix_mstruct->clear();
+ fwrite(&matrix_mstruct, sizeof(void*), 1, view_pipe_w);
+ } else {
+ MathStructure *mreg = CALCULATOR->getRPNRegister(stack_index + 1);
+ fwrite(&mreg, sizeof(void*), 1, view_pipe_w);
+ void *x = NULL;
+ fwrite(&x, sizeof(void*), 1, view_pipe_w);
+ }
+ bool *b = &do_wrap;
+ fwrite(&b, sizeof(bool*), 1, view_pipe_w);
+ if(update_parse) {
+ fwrite(&parsed_mstruct, sizeof(void*), 1, view_pipe_w);
+ bool *parsed_approx_p = &parsed_approx;
+ fwrite(&parsed_approx_p, sizeof(void*), 1, view_pipe_w);
+ fwrite(&parsed_tostruct, sizeof(void*), 1, view_pipe_w);
+ } else {
+ void *x = NULL;
+ fwrite(&x, sizeof(void*), 1, view_pipe_w);
+ }
+ fflush(view_pipe_w);
+
+ struct timespec rtime;
+ rtime.tv_sec = 0;
+ rtime.tv_nsec = 20000000;
+ int i = 0;
+ while(b_busy && i < 50) {
+ nanosleep(&rtime, NULL);
+ i++;
+ }
+ i = 0;
+
+ KProgressDialog *dialog = NULL;
+ if(b_busy) {
+ dialog = new KProgressDialog(this, "display_progress_dialog", i18n("Processing..."), i18n("Processing..."), true);
+ dialog->progressBar()->setPercentageVisible(false);
+ dialog->progressBar()->setTotalSteps(0);
+ dialog->showCancelButton(true);
+ dialog->setButtonText(i18n("Abort"));
+ dialog->show();
+ }
+ if(dialog && dialog->wasCancelled()) on_abort_display();
+ rtime.tv_nsec = 100000000;
+ while(b_busy) {
+ dialog->progressBar()->advance(1);
+ qApp->processEvents();
+ nanosleep(&rtime, NULL);
+ if(dialog->wasCancelled()) on_abort_display();
+ }
+
+ b_busy = true;
+ if(dialog) {
+ dialog->hide();
+ delete dialog;
+ }
+
+ if(stack_index == 0) {
+ if(do_wrap) {
+ resultLabel->setVScrollBarMode(QScrollView::Auto);
+ resultLabel->setRightMargin(10);
+ resultLabel->setWordWrap(QTextEdit::NoWrap);
+ } else {
+ resultLabel->setVScrollBarMode(QScrollView::AlwaysOff);
+ resultLabel->setWordWrap(QTextEdit::NoWrap);
+ resultLabel->setRightMargin(0);
+ QString str = result_text;
+ str.replace("width=1 ", "");
+ QSimpleRichText testrt(str, resultLabel->font());
+ testrt.setWidth(resultLabel->visibleWidth() * 4);
+ if(testrt.widthUsed() > resultLabel->visibleWidth()) {
+ result_text.replace("<font size=5", "<font size=4");
+ result_text.replace("<font size=6", "<font size=5");
+ reduceDivLineSize(resultLabel);
+ }
+ }
+ resultLabel->setText(result_text);
+ }
+
+ if(register_moved) {
+ update_parse = true;
+ parsed_text = result_history_text;
+ }
+
+ if(update_history) {
+ if(result_history_text.length() > 500000) {
+ result_history_text = "(...)";
+ }
+ if(parsed_text.length() > 500000) {
+ parsed_text = "(...)";
+ }
+ QString new_text;
+ if(update_parse) {
+ QString str = "&nbsp;&nbsp;";
+ if(!parsed_approx) {
+ str += "=";
+ inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_PARSE);
+ } else {
+ if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) historyBrowser)) {
+ str += SIGN_ALMOST_EQUAL;
+ } else {
+ str += i18n("approx.");
+ }
+ inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_PARSE_APPROXIMATE);
+ }
+ str += " ";
+ QString str2 = parsed_text;
+ str2.replace("&", "&amp;");
+ str2.replace(">", "&gt;");
+ str2.replace("<", "&lt;");
+ inhistory.insert(inhistory.begin() + inhistory_index, str2);
+ inhistory_id.insert(inhistory_id.begin() + inhistory_index, inhistory_current_id);
+ inhistory_index++;
+ str += str2;
+ new_text += "<font color=\"gray40\"><i>";
+ new_text += "<a name=\"";
+ new_text += QString::number(inhistory_current_id);
+ new_text += "\">";
+ new_text += str;
+ new_text += "</a>";
+ new_text += "</i></font>";
+ new_text += "<br>";
+ inhistory_current_id++;
+ }
+ if(stack_index == 0) {
+ display_errors(&new_text, &inhistory_index);
+ new_text += "<a name=\"";
+ new_text += QString::number(inhistory_current_id);
+ new_text += "\">";
+ if(!(*printops.is_approximate) && !mstruct->isApproximate() && (update_parse || !prev_result_approx)) {
+ inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_RESULT);
+ new_text += "=";
+ } else {
+ inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_RESULT_APPROXIMATE);
+ if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) historyBrowser)) {
+ new_text += SIGN_ALMOST_EQUAL;
+ } else {
+ QString str_approx = "= ";
+ str_approx += i18n("approx.");
+ new_text += str_approx;
+ }
+ }
+ new_text += " ";
+ new_text += "</a>";
+ } else {
+ display_errors();
+ }
+ if(rpn_mode && !register_moved) {
+ RPNRegisterChanged(result_history_text, stack_index);
+ }
+ if(stack_index == 0) {
+ QString str2 = result_history_text;
+ str2.replace("&", "&amp;");
+ str2.replace(">", "&gt;");
+ str2.replace("<", "&lt;");
+ new_text += "<b>";
+ new_text += "<a name=\"";
+ new_text += QString::number(inhistory_current_id);
+ new_text += "\">";
+ new_text += str2;
+ new_text += " </a>";
+ new_text += "</b>";
+ inhistory.insert(inhistory.begin() + inhistory_index, str2);
+ inhistory_id.insert(inhistory_id.begin() + inhistory_index, inhistory_current_id);
+ inhistory_current_id++;
+ QString text = historyBrowser->text();
+ initial_result_index = history_index + new_text.length() + 4;
+ initial_inhistory_index = inhistory_index + 1;
+ if(!update_parse && transformation.isEmpty()) {
+ new_text += "<br>";
+ }
+ text.insert(history_index, new_text);
+ historyBrowser->setText(text);
+ prev_result_approx = *printops.is_approximate;
+ }
+ }
+ printops.prefix = NULL;
+
+ b_busy = false;
+ display_errors();
+
+ if(!register_moved && stack_index == 0 && mstruct->isMatrix() && matrix_mstruct->isMatrix()) {
+ qApp->processEvents();
+ expressionEdit->setFocus();
+ if(update_history && update_parse && force) expressionEdit->selectAll();
+ insertMatrixVector(matrix_mstruct, false, true, true);
+ }
+ error_timer->start(100);
+}
+
+void on_abort_command() {
+ pthread_cancel(command_thread);
+ CALCULATOR->restoreState();
+ CALCULATOR->clearBuffers();
+ b_busy = false;
+ command_thread_started = false;
+}
+
+void *command_proc(void *pipe) {
+
+ pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+ pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
+ FILE *command_pipe = (FILE*) pipe;
+
+ while(true) {
+
+ void *x = NULL;
+ int command_type;
+ fread(&command_type, sizeof(int), 1, command_pipe);
+ fread(&x, sizeof(void*), 1, command_pipe);
+ switch(command_type) {
+ case COMMAND_FACTORIZE: {
+ if(!((MathStructure*) x)->integerFactorize()) {
+ ((MathStructure*) x)->factorize(evalops);
+ }
+ break;
+ }
+ case COMMAND_SIMPLIFY: {
+ ((MathStructure*) x)->simplify(evalops);
+ break;
+ }
+ }
+ b_busy = false;
+
+ }
+ return NULL;
+}
+
+int execute_command_command_type;
+
+void KQalculate::executeCommand(int command_type) {
+ execute_command_command_type = command_type;
+ if(expression_has_changed && !rpn_mode) {
+ execute_expression();
+ }
+ QTimer::singleShot(0, this, SLOT(executeCommand2()));
+}
+void KQalculate::executeCommand2() {
+ int command_type = execute_command_command_type;
+
+ error_timer->stop();
+
+ b_busy = true;
+ bool command_aborted = false;
+ CALCULATOR->saveState();
+
+ if(!command_thread_started) {
+ pthread_create(&command_thread, &command_thread_attr, command_proc, command_pipe_r);
+ command_thread_started = true;
+ }
+
+ fwrite(&command_type, sizeof(int), 1, command_pipe_w);
+ MathStructure *mfactor = new MathStructure(*mstruct);
+ fwrite(&mfactor, sizeof(void*), 1, command_pipe_w);
+
+ fflush(command_pipe_w);
+
+ struct timespec rtime;
+ rtime.tv_sec = 0;
+ rtime.tv_nsec = 20000000;
+ int i = 0;
+ while(b_busy && i < 50) {
+ nanosleep(&rtime, NULL);
+ i++;
+ }
+ i = 0;
+
+ KProgressDialog *dialog = NULL;
+ if(b_busy) {
+ QString progress_str;
+ switch(command_type) {
+ case COMMAND_FACTORIZE: {
+ progress_str = i18n("Factorizing...");
+ break;
+ }
+ case COMMAND_SIMPLIFY: {
+ progress_str = i18n("Simplifying...");
+ break;
+ }
+ }
+ dialog = new KProgressDialog(this, "display_progress_dialog", progress_str, progress_str, true);
+ dialog->progressBar()->setPercentageVisible(false);
+ dialog->progressBar()->setTotalSteps(0);
+ dialog->showCancelButton(true);
+ dialog->setButtonText(i18n("Abort"));
+ dialog->show();
+ }
+ if(dialog && dialog->wasCancelled()) {
+ on_abort_command();
+ command_aborted = true;
+ }
+ rtime.tv_nsec = 100000000;
+ while(b_busy) {
+ dialog->progressBar()->advance(1);
+ qApp->processEvents();
+ nanosleep(&rtime, NULL);
+ if(dialog->wasCancelled()) {
+ on_abort_command();
+ command_aborted = true;
+ }
+ }
+
+ b_busy = true;
+ if(dialog) {
+ dialog->hide();
+ delete dialog;
+ }
+
+ b_busy = false;
+
+ if(!command_aborted) {
+ mstruct->unref();
+ mstruct = mfactor;
+ switch(command_type) {
+ case COMMAND_FACTORIZE: {
+ printops.allow_factorization = true;
+ break;
+ }
+ case COMMAND_SIMPLIFY: {
+ printops.allow_factorization = false;
+ break;
+ }
+ }
+ set_result_prefix = NULL;
+ set_result_update_history = true;
+ set_result_update_parse = false;
+ set_result_force = true;
+ set_result_transformation = "";
+ set_result_stack_index = 0;
+ set_result_register_moved = false;
+ setResult2();
+ expressionEdit->setFocus();
+ }
+
+ error_timer->start(100);
+
+}
+
+void KQalculate::result_display_updated() {
+ setResult(NULL, false, false, false);
+ update_status_text();
+ expressionEdit->setFocus();
+}
+void KQalculate::result_format_updated() {
+ setResult(NULL, true, false, false);
+ update_status_text();
+ expressionEdit->setFocus();
+}
+void KQalculate::result_action_executed() {
+ //display_errors();
+ printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
+ setResult(NULL, true, false, true);
+ expressionEdit->setFocus();
+}
+void KQalculate::result_prefix_changed(Prefix *prefix) {
+ setResult(prefix, true, false, true);
+ expressionEdit->setFocus();
+}
+void KQalculate::expression_calculation_updated() {
+ expression_has_changed2 = true;
+ displayParseStatus();
+ if(!rpn_mode) execute_expression(false);
+ update_status_text();
+ expressionEdit->setFocus();
+}
+void KQalculate::expression_format_updated(bool recalculate) {
+ if(rpn_mode) recalculate = false;
+ expression_has_changed2 = true;
+ displayParseStatus();
+ if(!expression_has_changed && !recalculate && !rpn_mode) {
+ clearresult();
+ }
+ if(recalculate) {
+ execute_expression(false);
+ }
+ update_status_text();
+ expressionEdit->setFocus();
+}
+
+/*
+ calculate entered expression and display result
+*/
+size_t execute_expression_stack_index;
+bool execute_expression_do_stack;
+bool execute_expression_force;
+bool execute_expression_do_mathoperation;
+MathOperation execute_expression_op;
+MathFunction *execute_expression_f;
+void KQalculate::execute_expression(bool force) {
+ execute_expression_force = force;
+ execute_expression_do_stack = false;
+ execute_expression_do_mathoperation = false;
+ QTimer::singleShot(0, this, SLOT(execute_expression2()));
+}
+void KQalculate::execute_expression2() {
+
+ bool force = execute_expression_force;
+ bool do_stack = execute_expression_do_stack;
+ size_t stack_index = execute_expression_stack_index;
+ bool do_mathoperation = execute_expression_do_mathoperation;
+ MathOperation op = execute_expression_op;
+ MathFunction *f = execute_expression_f;
+
+ QString str;
+
+ if(do_stack) {
+ str = getRPNRegister(stack_index)->text(1).stripWhiteSpace();
+ error_timer->stop();
+ } else {
+ str = expressionEdit->text().stripWhiteSpace();
+ if(!force && (expression_has_changed || str.isEmpty())) return;
+ error_timer->stop();
+ expression_has_changed = false;
+ if(!do_mathoperation && !str.isEmpty()) expressionEdit->addToHistory(expressionEdit->text());
+ }
+
+ size_t stack_size = 0;
+
+ b_busy = true;
+
+ if(!do_stack || stack_index == 0) {
+ parsed_text = "";
+ }
+ if(do_stack) {
+ stack_size = CALCULATOR->RPNStackSize();
+ CALCULATOR->setRPNRegister(stack_index + 1, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), 0, evalops, parsed_mstruct, parsed_tostruct, !printops.negative_exponents);
+ } else if(rpn_mode) {
+ stack_size = CALCULATOR->RPNStackSize();
+ if(do_mathoperation) {
+ if(f) CALCULATOR->calculateRPN(f, 0, evalops, parsed_mstruct);
+ else CALCULATOR->calculateRPN(op, 0, evalops, parsed_mstruct);
+ } else {
+ string str2 = CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options);
+ CALCULATOR->parseSigns(str2);
+ if(str2.length() == 1) {
+ do_mathoperation = true;
+ switch(str2[0]) {
+ case '^': {CALCULATOR->calculateRPN(OPERATION_RAISE, 0, evalops, parsed_mstruct); break;}
+ case '+': {CALCULATOR->calculateRPN(OPERATION_ADD, 0, evalops, parsed_mstruct); break;}
+ case '-': {CALCULATOR->calculateRPN(OPERATION_SUBTRACT, 0, evalops, parsed_mstruct); break;}
+ case '*': {CALCULATOR->calculateRPN(OPERATION_MULTIPLY, 0, evalops, parsed_mstruct); break;}
+ case '/': {CALCULATOR->calculateRPN(OPERATION_DIVIDE, 0, evalops, parsed_mstruct); break;}
+ case '&': {CALCULATOR->calculateRPN(OPERATION_BITWISE_AND, 0, evalops, parsed_mstruct); break;}
+ case '|': {CALCULATOR->calculateRPN(OPERATION_BITWISE_OR, 0, evalops, parsed_mstruct); break;}
+ case '~': {CALCULATOR->calculateRPNBitwiseNot(0, evalops, parsed_mstruct); break;}
+ case '!': {CALCULATOR->calculateRPN(CALCULATOR->f_factorial, 0, evalops, parsed_mstruct); break;}
+ case '>': {CALCULATOR->calculateRPN(OPERATION_GREATER, 0, evalops, parsed_mstruct); break;}
+ case '<': {CALCULATOR->calculateRPN(OPERATION_LESS, 0, evalops, parsed_mstruct); break;}
+ case '=': {CALCULATOR->calculateRPN(OPERATION_EQUALS, 0, evalops, parsed_mstruct); break;}
+ default: {do_mathoperation = false;}
+ }
+ } else if(str2.length() == 2) {
+ if(str2 == "**") {
+ CALCULATOR->calculateRPN(OPERATION_RAISE, 0, evalops, parsed_mstruct);
+ do_mathoperation = true;
+ } else if(str2 == "!!") {
+ CALCULATOR->calculateRPN(CALCULATOR->f_factorial2, 0, evalops, parsed_mstruct);
+ do_mathoperation = true;
+ } else if(str2 == "!=" || str == "=!" || str == "<>") {
+ CALCULATOR->calculateRPN(OPERATION_NOT_EQUALS, 0, evalops, parsed_mstruct);
+ do_mathoperation = true;
+ } else if(str2 == "<=" || str == "=<") {
+ CALCULATOR->calculateRPN(OPERATION_EQUALS_LESS, 0, evalops, parsed_mstruct);
+ do_mathoperation = true;
+ } else if(str2 == ">=" || str == "=>") {
+ CALCULATOR->calculateRPN(OPERATION_EQUALS_GREATER, 0, evalops, parsed_mstruct);
+ do_mathoperation = true;
+ } else if(str2 == "==") {
+ CALCULATOR->calculateRPN(OPERATION_EQUALS, 0, evalops, parsed_mstruct);
+ do_mathoperation = true;
+ }
+ }
+ if(!do_mathoperation) {
+ bool had_nonnum = false, test_function = true;
+ int in_par = 0;
+ for(size_t i = 0; i < str2.length(); i++) {
+ if(is_in(NUMBERS, str2[i])) {
+ if(!had_nonnum || in_par) {
+ test_function = false;
+ break;
+ }
+ } else if(str2[i] == '(') {
+ if(in_par || !had_nonnum) {
+ test_function = false;
+ break;
+ }
+ in_par = i;
+ } else if(str2[i] == ')') {
+ if(i != str2.length() - 1) {
+ test_function = false;
+ break;
+ }
+ } else if(str2[i] == ' ') {
+ if(!in_par) {
+ test_function = false;
+ break;
+ }
+ } else if(is_in(NOT_IN_NAMES, str2[i])) {
+ test_function = false;
+ break;
+ } else {
+ if(in_par) {
+ test_function = false;
+ break;
+ }
+ had_nonnum = true;
+ }
+ }
+ f = NULL;
+ if(test_function) {
+ if(in_par) f = CALCULATOR->getActiveFunction(str2.substr(0, in_par));
+ else f = CALCULATOR->getActiveFunction(str2);
+ }
+ if(f && f->minargs() > 1) {
+ KMessageBox::error(this, "Can only apply functions wich requires one argument on RPN stack.");
+ f = NULL;
+ return;
+ }
+ if(f && f->minargs() > 0) {
+ do_mathoperation = true;
+ CALCULATOR->calculateRPN(f, 0, evalops, parsed_mstruct);
+ } else {
+ CALCULATOR->RPNStackEnter(str2, 0, evalops, parsed_mstruct, parsed_tostruct, !printops.negative_exponents);
+ }
+ }
+ }
+ } else {
+ CALCULATOR->calculate(mstruct, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), 0, evalops, parsed_mstruct, parsed_tostruct, !printops.negative_exponents);
+ }
+ struct timespec rtime;
+ rtime.tv_sec = 0;
+ rtime.tv_nsec = 20000000;
+ int i = 0;
+ while(CALCULATOR->busy() && i < 50) {
+ nanosleep(&rtime, NULL);
+ i++;
+ }
+ i = 0;
+ KProgressDialog *dialog = NULL;
+ if(CALCULATOR->busy()) {
+ dialog = new KProgressDialog(this, "calculation_progress_dialog", i18n("Calculating..."), i18n("Calculating..."), true);
+ dialog->progressBar()->setPercentageVisible(false);
+ dialog->progressBar()->setTotalSteps(0);
+ dialog->showCancelButton(true);
+ dialog->setButtonText(i18n("Abort"));
+ dialog->show();
+ }
+ if(dialog && dialog->wasCancelled()) CALCULATOR->abort();
+ rtime.tv_nsec = 100000000;
+ while(CALCULATOR->busy()) {
+ dialog->progressBar()->advance(1);
+ qApp->processEvents();
+ nanosleep(&rtime, NULL);
+ if(dialog->wasCancelled()) CALCULATOR->abort();
+ }
+ if(dialog) {
+ dialog->hide();
+ delete dialog;
+ expressionEdit->setFocus();
+ }
+ b_busy = false;
+
+ if(rpn_mode && (!do_stack || stack_index == 0)) {
+ mstruct->unref();
+ mstruct = CALCULATOR->getRPNRegister(1);
+ if(!mstruct) mstruct = new MathStructure();
+ else mstruct->ref();
+ }
+
+ //update "ans" variables
+ if(!do_stack || stack_index == 0) {
+ vans[4]->set(vans[3]->get());
+ vans_id_start[4] = vans_id_start[3];
+ vans_id_end[4] = vans_id_end[3];
+ vans[3]->set(vans[2]->get());
+ vans_id_start[3] = vans_id_start[2];
+ vans_id_end[3] = vans_id_end[2];
+ vans[2]->set(vans[1]->get());
+ vans_id_start[2] = vans_id_start[1];
+ vans_id_end[2] = vans_id_end[1];
+ vans[1]->set(vans[0]->get());
+ vans_id_start[1] = vans_id_start[0];
+ vans_id_end[1] = inhistory_current_id - 1;
+ vans[0]->set(*mstruct);
+ vans_id_start[0] = inhistory_current_id;
+ vans_id_end[0] = -1;
+ }
+
+ if(do_stack && stack_index > 0) {
+ } else if(rpn_mode && do_mathoperation) {
+ result_history_text = i18n("RPN Operation");
+ } else {
+ result_history_text = str;
+ }
+ printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
+ set_result_prefix = NULL;
+ set_result_update_history = true;
+ set_result_update_parse = (!do_stack || stack_index == 0);
+ set_result_force = true;
+ set_result_transformation = "";
+ set_result_register_moved = false;
+ if(!do_stack) set_result_stack_index = 0;
+ else set_result_stack_index = stack_index;
+ if(rpn_mode && (!do_stack || stack_index == 0)) {
+ expressionEdit->clear();
+ if(CALCULATOR->RPNStackSize() < stack_size) {
+ RPNRegisterRemoved(1);
+ } else if(CALCULATOR->RPNStackSize() > stack_size) {
+ RPNRegisterAdded("");
+ }
+ }
+ setResult2();
+ if(!do_stack || stack_index == 0) {
+ expressionEdit->setFocus();
+ expressionEdit->selectAll();
+ }
+ error_timer->start(100);
+}
+
+void KQalculate::display_errors(QString *new_text, int *inhistory_index) {
+ if(!CALCULATOR->message()) return;
+ error_timer->stop();
+ bool error = false;
+ MessageType mtype;
+ QStringList strlst;
+ QString error_str = "";
+ while(true) {
+ mtype = CALCULATOR->message()->type();
+ if(mtype == MESSAGE_ERROR || mtype == MESSAGE_WARNING) {
+ QString text = CALCULATOR->message()->message().c_str();
+ text.replace("&", "&amp;");
+ text.replace(">", "&gt;");
+ text.replace("<", "&lt;");
+ if(inhistory_index) {
+ inhistory.insert(inhistory.begin() + *inhistory_index, text);
+ inhistory_id.insert(inhistory_id.begin() + *inhistory_index, inhistory_current_id);
+ inhistory_current_id++;
+ if(mtype == MESSAGE_ERROR) inhistory_type.insert(inhistory_type.begin() + *inhistory_index, QALCULATE_HISTORY_ERROR);
+ else inhistory_type.insert(inhistory_type.begin() + *inhistory_index, QALCULATE_HISTORY_WARNING);
+ *inhistory_index += 1;
+ }
+ strlst.push_back(CALCULATOR->message()->message().c_str());
+ if(mtype == MESSAGE_ERROR) error = true;
+ if(mtype == MESSAGE_ERROR) error_str += "<font color=\"red\">";
+ else error_str += "<font color=\"blue\">";
+ error_str += "- ";
+ error_str += text;
+ error_str += "</font>";
+ error_str += "<br>";
+ } else {
+ KMessageBox::information(this, CALCULATOR->message()->message().c_str());
+ }
+ if(!CALCULATOR->nextMessage()) break;
+ }
+ if(!error_str.isEmpty() && new_text) {
+ new_text->append(error_str);
+ }
+ if(strlst.size() > 1) {
+ if(error) KMessageBox::error(this, strlst.join("\n"), i18n("Errors"));
+ else KMessageBox::error(this, strlst.join("\n"), i18n("Warnings"));
+ } else if(strlst.size() == 1) {
+ if(error) KMessageBox::error(this, strlst[0], i18n("Error"));
+ else KMessageBox::error(this, strlst[0], i18n("Warning"));
+ }
+ error_timer->start(100);
+}
+
+void save_defs() {
+ if(!CALCULATOR->saveDefinitions()) {
+ KMessageBox::error(0, i18n("Couldn't write definitions"));
+ }
+}
+
+
+void KQalculate::create_vmenu() {
+
+ QPopupMenu *sub, *sub3;
+
+ menu_variables->clear();
+ sub = menu_variables;
+ Variable *v;
+ tree_struct *titem, *titem2;
+ variable_cats.rit = variable_cats.items.rbegin();
+ if(variable_cats.rit != variable_cats.items.rend()) {
+ titem = &*variable_cats.rit;
+ ++variable_cats.rit;
+ titem->rit = titem->items.rbegin();
+ } else {
+ titem = NULL;
+ }
+
+ menu_variables_ids.clear();
+
+ stack<QPopupMenu*> menus;
+ menus.push(sub);
+ sub3 = sub;
+ while(titem) {
+ sub = new QPopupMenu();
+ QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onVariableMenuItemActivated(int)));
+ if(titem->item.find('&') != string::npos) {
+ QString str2 = titem->item.c_str();
+ str2.replace("&", "&&");
+ sub3->insertItem(str2, sub, -1, 0);
+ } else {
+ sub3->insertItem(titem->item.c_str(), sub, -1, 0);
+ }
+ menus.push(sub);
+ sub3 = sub;
+ for(size_t i = 0; i < titem->objects.size(); i++) {
+ v = (Variable*) titem->objects[i];
+ if(v->isActive() && !v->isHidden()) {
+ if(v->title(true).find('&') != string::npos) {
+ QString str2 = v->title(true).c_str();
+ str2.replace("&", "&&");
+ menu_variables_ids[sub->insertItem(str2)] = v;
+ } else {
+ menu_variables_ids[sub->insertItem(v->title(true).c_str())] = v;
+ }
+ }
+ }
+ while(titem && titem->rit == titem->items.rend()) {
+ titem = titem->parent;
+ menus.pop();
+ if(menus.size() > 0) sub3 = menus.top();
+ }
+ if(titem) {
+ titem2 = &*titem->rit;
+ ++titem->rit;
+ titem = titem2;
+ titem->rit = titem->items.rbegin();
+ }
+
+ }
+
+ for(size_t i = 0; i < variable_cats.objects.size(); i++) {
+ v = (Variable*) variable_cats.objects[i];
+ if(v->isActive() && !v->isHidden()) {
+ menu_variables_ids[menu_variables->insertItem(v->title(true).c_str())] = v;
+ }
+ }
+
+}
+
+void KQalculate::recreate_recent_variables() {
+ recent_variable_ids.clear();
+ bool b = false;
+ for(size_t i = 0; i < recent_variables.size(); i++) {
+ if(!CALCULATOR->stillHasVariable(recent_variables[i])) {
+ recent_variables.erase(recent_variables.begin() + i);
+ i--;
+ } else {
+ if(!b) {
+ menu_variables->insertSeparator(0);
+ b = true;
+ }
+ int id = menu_variables->insertItem(recent_variables[i]->title(true).c_str(), -1, 0);
+ recent_variable_ids.push_back(id);
+ menu_variables_ids[id] = recent_variables[i];
+ }
+ }
+}
+void KQalculate::update_vmenu() {
+ generate_variables_tree_struct();
+ create_vmenu();
+ recreate_recent_variables();
+ if(variables_dialog) variables_dialog->updateVariableTree();
+ update_completion();
+}
+
+void KQalculate::create_fmenu() {
+
+ QPopupMenu *sub, *sub3;
+
+ menu_functions->clear();
+ sub = menu_functions;
+ MathFunction *f;
+ tree_struct *titem, *titem2;
+ function_cats.rit = function_cats.items.rbegin();
+ if(function_cats.rit != function_cats.items.rend()) {
+ titem = &*function_cats.rit;
+ ++function_cats.rit;
+ titem->rit = titem->items.rbegin();
+ } else {
+ titem = NULL;
+ }
+
+ menu_functions_ids.clear();
+
+ stack<QPopupMenu*> menus;
+ menus.push(sub);
+ sub3 = sub;
+ while(titem) {
+ sub = new QPopupMenu();
+ QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onFunctionMenuItemActivated(int)));
+ if(titem->item.find('&') != string::npos) {
+ QString str2 = titem->item.c_str();
+ str2.replace("&", "&&");
+ sub3->insertItem(str2, sub, -1, 0);
+ } else {
+ sub3->insertItem(titem->item.c_str(), sub, -1, 0);
+ }
+ menus.push(sub);
+ sub3 = sub;
+ for(size_t i = 0; i < titem->objects.size(); i++) {
+ f = (MathFunction*) titem->objects[i];
+ if(f->isActive() && !f->isHidden()) {
+ if(f->title(true).find('&') != string::npos) {
+ QString str2 = f->title(true).c_str();
+ str2.replace("&", "&&");
+ menu_functions_ids[sub->insertItem(str2)] = f;
+ } else {
+ menu_functions_ids[sub->insertItem(f->title(true).c_str())] = f;
+ }
+ }
+ }
+ while(titem && titem->rit == titem->items.rend()) {
+ titem = titem->parent;
+ menus.pop();
+ if(menus.size() > 0) sub3 = menus.top();
+ }
+ if(titem) {
+ titem2 = &*titem->rit;
+ ++titem->rit;
+ titem = titem2;
+ titem->rit = titem->items.rbegin();
+ }
+
+ }
+
+ for(size_t i = 0; i < function_cats.objects.size(); i++) {
+ f = (MathFunction*) function_cats.objects[i];
+ if(f->isActive() && !f->isHidden()) {
+ menu_functions_ids[menu_functions->insertItem(f->title(true).c_str())] = f;
+ }
+ }
+
+}
+void KQalculate::recreate_recent_functions() {
+ recent_function_ids.clear();
+ bool b = false;
+ for(size_t i = 0; i < recent_functions.size(); i++) {
+ if(!CALCULATOR->stillHasFunction(recent_functions[i])) {
+ recent_functions.erase(recent_functions.begin() + i);
+ i--;
+ } else {
+ if(!b) {
+ menu_functions->insertSeparator(0);
+ b = true;
+ }
+ int id = menu_functions->insertItem(recent_functions[i]->title(true).c_str(), -1, 0);
+ recent_function_ids.push_back(id);
+ menu_functions_ids[id] = recent_functions[i];
+ }
+ }
+}
+void KQalculate::update_fmenu() {
+ generate_functions_tree_struct();
+ create_fmenu();
+ recreate_recent_functions();
+ if(functions_dialog) functions_dialog->updateFunctionTree();
+ if(datasets_dialog) {
+ datasets_dialog->updateDataSetTree();
+ if(!datasets_dialog->dataSetsView->selectedItem()) datasets_dialog->dataSetSelected();
+ }
+ update_completion();
+}
+
+void KQalculate::create_umenu() {
+
+ QPopupMenu *sub, *sub3;
+
+ menu_units->clear();
+ sub = menu_units;
+ Unit *u;
+ tree_struct *titem, *titem2;
+ unit_cats.rit = unit_cats.items.rbegin();
+ if(unit_cats.rit != unit_cats.items.rend()) {
+ titem = &*unit_cats.rit;
+ ++unit_cats.rit;
+ titem->rit = titem->items.rbegin();
+ } else {
+ titem = NULL;
+ }
+
+ menu_units_ids.clear();
+
+ stack<QPopupMenu*> menus;
+ menus.push(sub);
+ sub3 = sub;
+ while(titem) {
+ sub = new QPopupMenu();
+ QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onUnitMenuItemActivated(int)));
+ if(titem->item.find('&') != string::npos) {
+ QString str2 = titem->item.c_str();
+ str2.replace("&", "&&");
+ sub3->insertItem(str2, sub, -1, 0);
+ } else {
+ sub3->insertItem(titem->item.c_str(), sub, -1, 0);
+ }
+ menus.push(sub);
+ sub3 = sub;
+ for(size_t i = 0; i < titem->objects.size(); i++) {
+ u = (Unit*) titem->objects[i];
+ if(u->isActive() && !u->isHidden()) {
+ if(u->title(true).find('&') != string::npos) {
+ QString str2 = u->title(true).c_str();
+ str2.replace("&", "&&");
+ menu_units_ids[sub->insertItem(str2)] = u;
+ } else {
+ menu_units_ids[sub->insertItem(u->title(true).c_str())] = u;
+ }
+ }
+ }
+ while(titem && titem->rit == titem->items.rend()) {
+ titem = titem->parent;
+ menus.pop();
+ if(menus.size() > 0) sub3 = menus.top();
+ }
+ if(titem) {
+ titem2 = &*titem->rit;
+ ++titem->rit;
+ titem = titem2;
+ titem->rit = titem->items.rbegin();
+ }
+
+ }
+
+ for(size_t i = 0; i < unit_cats.objects.size(); i++) {
+ u = (Unit*) unit_cats.objects[i];
+ if(u->isActive() && !u->isHidden()) {
+ menu_units_ids[menu_units->insertItem(u->title(true).c_str())] = u;
+ }
+ }
+
+ sub = new QPopupMenu();
+ QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onUnitsPrefixMenuItemActivated(int)));
+ menu_units->insertSeparator();
+ menu_units->insertItem(i18n("Prefixes"), sub);
+ int index = 0;
+ Prefix *p = CALCULATOR->getPrefix(index);
+ while(p) {
+ QString pstr;
+ switch(p->type()) {
+ case PREFIX_DECIMAL: {
+ QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str() << "\t(10e" << ((DecimalPrefix*) p)->exponent() << ")";
+ break;
+ }
+ case PREFIX_BINARY: {
+ QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str() << "\t(2e" << ((BinaryPrefix*) p)->exponent() << ")";
+ break;
+ }
+ case PREFIX_NUMBER: {
+ QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str();
+ break;
+ }
+ }
+ menu_units_prefixes_ids[sub->insertItem(pstr)] = p;
+ index++;
+ p = CALCULATOR->getPrefix(index);
+ }
+
+}
+
+void KQalculate::recreate_recent_units() {
+ recent_unit_ids.clear();
+ bool b = false;
+ for(size_t i = 0; i < recent_units.size(); i++) {
+ if(!CALCULATOR->stillHasUnit(recent_units[i])) {
+ recent_units.erase(recent_units.begin() + i);
+ i--;
+ } else {
+ if(!b) {
+ menu_units->insertSeparator(0);
+ b = true;
+ }
+ int id = menu_units->insertItem(recent_units[i]->title(true).c_str(), -1, 0);
+ recent_unit_ids.push_back(id);
+ menu_units_ids[id] = recent_units[i];
+ }
+ }
+}
+void KQalculate::update_umenus() {
+ generate_units_tree_struct();
+ create_umenu();
+ recreate_recent_units();
+ create_toumenu();
+ if(units_dialog) units_dialog->updateUnitTree();
+ if(convert_to_unit_expression_dialog) convert_to_unit_expression_dialog->updateUnitTree();
+ update_completion();
+}
+
+void KQalculate::create_toumenu() {
+
+ QPopupMenu *sub, *sub3;
+
+ menu_to_unit->clear();
+ sub = menu_to_unit;
+ Unit *u;
+ tree_struct *titem, *titem2;
+ unit_cats.rit = unit_cats.items.rbegin();
+ if(unit_cats.rit != unit_cats.items.rend()) {
+ titem = &*unit_cats.rit;
+ ++unit_cats.rit;
+ titem->rit = titem->items.rbegin();
+ } else {
+ titem = NULL;
+ }
+
+ menu_to_unit_ids.clear();
+
+ stack<QPopupMenu*> menus;
+ menus.push(sub);
+ sub3 = sub;
+ while(titem) {
+ sub = new QPopupMenu();
+ QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onConvertToUnitMenuItemActivated(int)));
+ if(titem->item.find('&') != string::npos) {
+ QString str2 = titem->item.c_str();
+ str2.replace("&", "&&");
+ sub3->insertItem(str2, sub, -1, 0);
+ } else {
+ sub3->insertItem(titem->item.c_str(), sub, -1, 0);
+ }
+ menus.push(sub);
+ sub3 = sub;
+ for(size_t i = 0; i < titem->objects.size(); i++) {
+ u = (Unit*) titem->objects[i];
+ if(u->isActive() && !u->isHidden()) {
+ if(u->title(true).find('&') != string::npos) {
+ QString str2 = u->title(true).c_str();
+ str2.replace("&", "&&");
+ menu_to_unit_ids[sub->insertItem(str2)] = u;
+ } else {
+ menu_to_unit_ids[sub->insertItem(u->title(true).c_str())] = u;
+ }
+ }
+ }
+ while(titem && titem->rit == titem->items.rend()) {
+ titem = titem->parent;
+ menus.pop();
+ if(menus.size() > 0) sub3 = menus.top();
+ }
+ if(titem) {
+ titem2 = &*titem->rit;
+ ++titem->rit;
+ titem = titem2;
+ titem->rit = titem->items.rbegin();
+ }
+
+ }
+
+ for(size_t i = 0; i < unit_cats.objects.size(); i++) {
+ u = (Unit*) unit_cats.objects[i];
+ if(u->isActive() && !u->isHidden()) {
+ menu_to_unit_ids[menu_to_unit->insertItem(u->title(true).c_str())] = u;
+ }
+ }
+
+}
+
+void KQalculate::create_setpmenu() {
+ menu_set_prefix->clear();
+ QObject::connect(menu_set_prefix, SIGNAL(activated(int)), this, SLOT(onSetPrefixMenuItemActivated(int)));
+ int index = 0;
+ menu_set_prefix_ids[menu_set_prefix->insertItem(i18n("No Prefix"))] = CALCULATOR->decimal_null_prefix;
+ Prefix *p = CALCULATOR->getPrefix(index);
+ while(p) {
+ QString pstr;
+ switch(p->type()) {
+ case PREFIX_DECIMAL: {
+ QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str() << "\t(10e" << ((DecimalPrefix*) p)->exponent() << ")";
+ break;
+ }
+ case PREFIX_BINARY: {
+ QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str() << "\t(2e" << ((BinaryPrefix*) p)->exponent() << ")";
+ break;
+ }
+ case PREFIX_NUMBER: {
+ QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str();
+ break;
+ }
+ }
+ menu_set_prefix_ids[menu_set_prefix->insertItem(pstr)] = p;
+ index++;
+ p = CALCULATOR->getPrefix(index);
+ }
+}
+
+
+void KQalculate::insert_text(QString name) {
+ expressionEdit->insert(name);
+ expressionEdit->setFocus();
+}
+/*
+ insert one-argument function when button clicked
+*/
+void KQalculate::insertButtonFunction(QString text, bool append_space) {
+ if(expressionEdit->hasSelectedText()) {
+ //set selection as argument
+ text += "(";
+ text += expressionEdit->selectedText();
+ text += ")";
+ insert_text(text);
+ } else {
+ //one-argument functions do not need parenthesis
+ if(append_space) {
+ text += " ";
+ }
+ insert_text(text);
+ }
+}
+void KQalculate::insertButtonFunction(MathFunction *f) {
+ const ExpressionName *ename = &f->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit);
+ if(f->minargs() > 1) {
+ QString text = ename->name.c_str();
+ bool b = expressionEdit->hasSelectedText();
+ text += "(";
+ if(b) text += expressionEdit->selectedText();
+ for(int i = 1; i < f->minargs(); i++) {
+ text += CALCULATOR->getComma().c_str();
+ text += " ";
+ }
+ text += ")";
+ insert_text(text);
+ if(b) expressionEdit->cursorBackward(false, 1 + (f->minargs() - 2) * 2);
+ else expressionEdit->cursorBackward(false, 1 + (f->minargs() - 1) * 2);
+ } else {
+ if(rpn_mode && f->args() == 1) {
+ calculateRPN(f);
+ return;
+ }
+ insertButtonFunction(ename->name.c_str(), !text_length_is_one(ename->name));
+ }
+}
+
+void KQalculate::function_inserted(MathFunction *object) {
+ if(!object) {
+ return;
+ }
+ if(recent_function_ids.size() <= 0) {
+ menu_functions->insertSeparator(0);
+ }
+ for(size_t i = 0; i < recent_functions.size(); i++) {
+ if(recent_functions[i] == object) {
+ recent_functions.erase(recent_functions.begin() + i);
+ menu_functions->removeItem(recent_function_ids[i]);
+ recent_function_ids.erase(recent_function_ids.begin() + i);
+ break;
+ }
+ }
+ if(recent_function_ids.size() >= 5) {
+ recent_functions.erase(recent_functions.begin());
+ menu_functions->removeItem(recent_function_ids[0]);
+ recent_function_ids.erase(recent_function_ids.begin());
+ }
+ int id = menu_functions->insertItem(object->title(true).c_str(), -1, 0);
+ menu_functions_ids[id] = object;
+ recent_function_ids.push_back(id);
+ recent_functions.push_back(object);
+}
+void KQalculate::variable_inserted(Variable *object) {
+ if(!object) {
+ return;
+ }
+ if(recent_variable_ids.size() <= 0) {
+ menu_variables->insertSeparator(0);
+ }
+ for(size_t i = 0; i < recent_variables.size(); i++) {
+ if(recent_variables[i] == object) {
+ recent_variables.erase(recent_variables.begin() + i);
+ menu_variables->removeItem(recent_variable_ids[i]);
+ recent_variable_ids.erase(recent_variable_ids.begin() + i);
+ break;
+ }
+ }
+ if(recent_variable_ids.size() >= 5) {
+ recent_variables.erase(recent_variables.begin());
+ menu_variables->removeItem(recent_variable_ids[0]);
+ recent_variable_ids.erase(recent_variable_ids.begin());
+ }
+ int id = menu_variables->insertItem(object->title(true).c_str(), -1, 0);
+ menu_variables_ids[id] = object;
+ recent_variable_ids.push_back(id);
+ recent_variables.push_back(object);
+}
+void KQalculate::unit_inserted(Unit *object) {
+ if(!object) {
+ return;
+ }
+ if(recent_unit_ids.size() <= 0) {
+ menu_units->insertSeparator(0);
+ }
+ for(size_t i = 0; i < recent_units.size(); i++) {
+ if(recent_units[i] == object) {
+ recent_units.erase(recent_units.begin() + i);
+ menu_units->removeItem(recent_unit_ids[i]);
+ recent_unit_ids.erase(recent_unit_ids.begin() + i);
+ break;
+ }
+ }
+ if(recent_unit_ids.size() >= 5) {
+ recent_units.erase(recent_units.begin());
+ menu_units->removeItem(recent_unit_ids[0]);
+ recent_unit_ids.erase(recent_unit_ids.begin());
+ }
+ int id = menu_units->insertItem(object->title(true).c_str(), -1, 0);
+ menu_units_ids[id] = object;
+ recent_unit_ids.push_back(id);
+ recent_units.push_back(object);
+}
+
+void KQalculate::onVariableMenuItemActivated(int id) {
+ if(!menu_variables_ids.contains(id)) return;
+ Variable *v = menu_variables_ids[id];
+ if(!CALCULATOR->stillHasVariable(v)) {
+ KMessageBox::error(this, i18n("Variable does not exist anymore."));
+ update_vmenu();
+ return;
+ }
+ insert_text(v->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str());
+ variable_inserted(v);
+}
+void KQalculate::onFunctionMenuItemActivated(int id) {
+ if(!menu_functions_ids.contains(id)) return;
+ MathFunction *f = menu_functions_ids[id];
+ insertFunction(f, this);
+}
+void KQalculate::onUnitMenuItemActivated(int id) {
+ if(!menu_units_ids.contains(id)) return;
+ Unit *u = menu_units_ids[id];
+ if(!CALCULATOR->stillHasUnit(u)) {
+ KMessageBox::error(this, i18n("Unit does not exist anymore."));
+ update_umenus();
+ return;
+ }
+ if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) {
+ insert_text(((CompositeUnit*) u)->print(true, printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) expressionEdit).c_str());
+ } else {
+ insert_text(u->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, true, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str());
+ }
+ unit_inserted(u);
+}
+void KQalculate::onUnitsPrefixMenuItemActivated(int id) {
+ if(!menu_units_prefixes_ids.contains(id)) return;
+ insert_text(menu_units_prefixes_ids[id]->name(printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) expressionEdit).c_str());
+}
+
+void KQalculate::update_completion() {
+ expressionEdit->updateCompletion();
+ if(plot_dialog) {
+ plot_dialog->expressionEdit->updateCompletion();
+ }
+}
+
+void KQalculate::set_unicode_buttons() {
+ if(printops.use_unicode_signs) {
+ if(can_display_unicode_string_function(SIGN_MINUS, (void*) kpMinus)) kpMinus->setText(SIGN_MINUS);
+ else kpMinus->setText(MINUS);
+ if(can_display_unicode_string_function(SIGN_PLUS, (void*) kpPlus)) kpPlus->setText(SIGN_PLUS);
+ else kpPlus->setText(PLUS);
+ if(can_display_unicode_string_function(SIGN_MULTIPLICATION, (void*) kpTimes)) kpTimes->setText(SIGN_MULTIPLICATION);
+ else kpTimes->setText(MULTIPLICATION);
+ if(can_display_unicode_string_function(SIGN_DIVISION_SLASH, (void*) kpDivision)) kpDivision->setText(SIGN_DIVISION_SLASH);
+ else if(can_display_unicode_string_function(SIGN_DIVISION, (void*) kpDivision)) kpDivision->setText(SIGN_DIVISION);
+ else kpDivision->setText(DIVISION);
+ if(can_display_unicode_string_function(SIGN_SQRT, (void*) kpSqrt)) kpSqrt->setText(SIGN_SQRT);
+ else kpSqrt->setText("Sqrt");
+ if(can_display_unicode_string_function(SIGN_MULTIDOT, (void*) kpDot)) kpDot->setText(SIGN_MULTIDOT);
+ else kpDot->setText(CALCULATOR->getDecimalPoint().c_str());
+ } else {
+ kpMinus->setText(MINUS);
+ kpPlus->setText(PLUS);
+ kpTimes->setText(MULTIPLICATION);
+ kpDivision->setText(DIVISION);
+ kpSqrt->setText("Sqrt");
+ kpDot->setText(CALCULATOR->getDecimalPoint().c_str());
+ }
+}
+
+void KQalculate::onExpressionChanged() {
+ expression_has_changed = true;
+ expression_has_changed2 = true;
+ if(!rpn_mode) clearresult();
+ if(!expressionEdit->dont_change_index) expressionEdit->expression_history_index = -1;
+ displayParseStatus();
+}
+
+void KQalculate::execute() {
+ execute_expression_force = true;
+ execute_expression_do_stack = false;
+ execute_expression_do_mathoperation = false;
+ execute_expression2();
+}
+
+bool KQalculate::fetch_exchange_rates(int) {
+ KURL url(CALCULATOR->getExchangeRatesUrl().c_str());
+ QString filename(CALCULATOR->getExchangeRatesFileName().c_str());
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ if(KIO::NetAccess::download(url, filename)) {
+#else
+ if(KIO::NetAccess::download(url, filename, this)) {
+#endif
+ return true;
+ } else {
+ QString errorstr = i18n("Failed to download exchange rates from ECB.");
+ errorstr += "\n";
+ errorstr += KIO::NetAccess::lastErrorString();
+ KMessageBox::error(this, errorstr);
+ return false;
+ }
+}
+
+void KQalculate::onErrorTimeout() {
+ if(CALCULATOR->checkSaveFunctionCalled()) {
+ update_vmenu();
+ }
+ display_errors();
+}
+
+void KQalculate::toggleHistory(bool on) {
+ if(on) {
+ bool b = mainStack->isVisible();
+ int new_height = height();
+ if(bottomLine->isVisible()) new_height -= bottomLine->height();
+ if(mainStack->height() > history_height) history_height = mainStack->height();
+ bottomLine->hide();
+ mainStack->show();
+ mainStack->raiseWidget(1);
+ keypadButton->setOn(false);
+ stackButton->setOn(false);
+ mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
+ resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
+ if(!b) {
+ new_height += history_height;
+ resize(width(), new_height);
+ } else if(history_height != mainStack->height()) {
+ resize(width(), height() - mainStack->height() + history_height);
+ }
+ } else {
+ if(!keypadButton->isOn() && !stackButton->isOn()) {
+ history_height = mainStack->height();
+ int new_height = height() - mainStack->height();
+ mainStack->hide();
+ bottomLine->show();
+ qApp->processEvents();
+ if(new_height < height()) resize(width(), new_height + bottomLine->height());
+ mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
+ resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
+ }
+ }
+}
+
+void KQalculate::toggleStack(bool on) {
+ if(on) {
+ bool b = mainStack->isVisible();
+ int new_height = height();
+ if(bottomLine->isVisible()) new_height -= bottomLine->height();
+ if(mainStack->height() > history_height) history_height = mainStack->height();
+ bottomLine->hide();
+ mainStack->show();
+ mainStack->raiseWidget(2);
+ keypadButton->setOn(false);
+ historyButton->setOn(false);
+ mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
+ resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
+ if(!b) {
+ new_height += history_height;
+ resize(width(), new_height);
+ } else if(history_height != mainStack->height()) {
+ resize(width(), height() - mainStack->height() + history_height);
+ }
+ } else {
+ if(!keypadButton->isOn() && !historyButton->isOn()) {
+ history_height = mainStack->height();
+ int new_height = height() - mainStack->height();
+ mainStack->hide();
+ bottomLine->show();
+ qApp->processEvents();
+ if(new_height < height()) resize(width(), new_height + bottomLine->height());
+ mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
+ resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
+ }
+ }
+}
+
+void KQalculate::toggleKeypad(bool on) {
+ if(on) {
+ bool b = mainStack->isVisible();
+ if(b) history_height = mainStack->height();
+ int new_height = height() - bottomLine->height();
+ mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
+ resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
+ mainStack->show();
+ bottomLine->hide();
+ mainStack->raiseWidget(0);
+ historyButton->setOn(false);
+ stackButton->setOn(false);
+ if(!b) {
+ qApp->processEvents();
+ new_height += mainStack->height();
+ resize(width(), new_height);
+ } else {
+ resize(width(), minimumSizeHint().height());
+ }
+ } else {
+ if(!historyButton->isOn() && !stackButton->isOn()) {
+ int new_height = height() - mainStack->height();
+ mainStack->hide();
+ bottomLine->show();
+ qApp->processEvents();
+ if(new_height < height()) resize(width(), new_height + bottomLine->height());
+ mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false);
+ resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false);
+ }
+ }
+}
+
+void KQalculate::showHide() {
+ if(isVisible()) {
+ hide();
+ } else {
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ KWin::Info info = KWin::info(winId());
+ KWin::setOnDesktop(winId(), KWin::currentDesktop());
+ move(info.geometry.topLeft());
+#else
+ KWin::WindowInfo info = KWin::windowInfo(winId(), (unsigned long) NET::WMGeometry);
+ KWin::setOnDesktop(winId(), KWin::currentDesktop());
+ move(info.geometry().topLeft());
+#endif
+ setShown(true);
+ show();
+ raise();
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ KWin::setActiveWindow(winId());
+#else
+ KWin::activateWindow(winId());
+#endif
+ }
+}
+void KQalculate::configureGlobalShortcuts() {
+ KKeyDialog::configure(globalAccel, 0, false);
+ globalAccel->writeSettings();
+ globalAccel->updateConnections();
+}
+
+void KQalculate::abbreviateNames(bool b) {
+ printops.abbreviate_names = b;
+ result_format_updated();
+}
+
+void KQalculate::approximationAlwaysExact() {
+ kpExact->blockSignals(true);
+ evalops.approximation = APPROXIMATION_EXACT;
+ expression_calculation_updated();
+ kpExact->setOn(true);
+ kpExact->blockSignals(false);
+}
+void KQalculate::approximationTryExact() {
+ kpExact->blockSignals(true);
+ evalops.approximation = APPROXIMATION_TRY_EXACT;
+ expression_calculation_updated();
+ kpExact->setOn(false);
+ kpExact->blockSignals(false);
+}
+void KQalculate::approximationApproximate() {
+ kpExact->blockSignals(true);
+ evalops.approximation = APPROXIMATION_APPROXIMATE;
+ expression_calculation_updated();
+ kpExact->setOn(false);
+ kpExact->blockSignals(false);
+}
+
+void KQalculate::fractionalDisplayDecimal() {
+ kpFraction->blockSignals(true);
+ printops.number_fraction_format = FRACTION_DECIMAL;
+ result_format_updated();
+ kpFraction->setOn(false);
+ kpFraction->blockSignals(false);
+}
+void KQalculate::fractionalDisplayDecimalTryExact() {
+ kpFraction->blockSignals(true);
+ printops.number_fraction_format = FRACTION_DECIMAL_EXACT;
+ result_format_updated();
+ kpFraction->setOn(false);
+ kpFraction->blockSignals(false);
+}
+void KQalculate::fractionalDisplayFraction() {
+ kpFraction->blockSignals(true);
+ printops.number_fraction_format = FRACTION_FRACTIONAL;
+ result_format_updated();
+ kpFraction->setOn(true);
+ kpFraction->blockSignals(false);
+}
+void KQalculate::fractionalDisplayCombined() {
+ kpFraction->blockSignals(true);
+ printops.number_fraction_format = FRACTION_COMBINED;
+ result_format_updated();
+ kpFraction->setOn(true);
+ kpFraction->blockSignals(false);
+}
+
+void KQalculate::numericalDisplayNormal() {
+ kpNumericCombo->blockSignals(true);
+ printops.min_exp = EXP_PRECISION;
+ result_format_updated();
+ kpNumericCombo->setCurrentItem(0);
+ kpNumericCombo->blockSignals(false);
+}
+void KQalculate::numericalDisplayEngineering() {
+ kpNumericCombo->blockSignals(true);
+ printops.min_exp = EXP_BASE_3;
+ result_format_updated();
+ kpNumericCombo->setCurrentItem(1);
+ kpNumericCombo->blockSignals(false);
+}
+void KQalculate::numericalDisplayScientific() {
+ kpNumericCombo->blockSignals(true);
+ printops.min_exp = EXP_SCIENTIFIC;
+ result_format_updated();
+ kpNumericCombo->setCurrentItem(2);
+ kpNumericCombo->blockSignals(false);
+}
+void KQalculate::numericalDisplayPurelyScientific() {
+ kpNumericCombo->blockSignals(true);
+ printops.min_exp = EXP_PURE;
+ result_format_updated();
+ kpNumericCombo->setCurrentItem(3);
+ kpNumericCombo->blockSignals(false);
+}
+void KQalculate::numericalDisplaySimple() {
+ kpNumericCombo->blockSignals(true);
+ printops.min_exp = EXP_NONE;
+ result_format_updated();
+ kpNumericCombo->setCurrentItem(4);
+ kpNumericCombo->blockSignals(false);
+}
+
+void KQalculate::roundHalfwayNumbersToEven(bool b) {
+ printops.round_halfway_to_even = b;
+ result_format_updated();
+}
+
+
+void KQalculate::indicateInfiniteSeries(bool b) {
+ printops.indicate_infinite_series = b;
+ result_format_updated();
+}
+
+void KQalculate::sortMinusLast(bool b) {
+ printops.sort_options.minus_last = b;
+ result_format_updated();
+}
+
+void KQalculate::negativeExponents(bool b) {
+ printops.negative_exponents = b;
+ result_format_updated();
+}
+
+void KQalculate::showEndingZeroes(bool b) {
+ printops.show_ending_zeroes = b;
+ result_format_updated();
+}
+
+void KQalculate::updateBaseOther() {
+ if(set_base_dialog) {
+ set_base_dialog->outputBaseBox->blockSignals(true);
+ set_base_dialog->radiogroup_output->blockSignals(true);
+ set_base_dialog->outputBaseBox->setEnabled(false);
+ switch(printops.base) {
+ case BASE_BINARY: {
+ set_base_dialog->radiogroup_output->setButton(0);
+ break;
+ }
+ case BASE_OCTAL: {
+ set_base_dialog->radiogroup_output->setButton(1);
+ break;
+ }
+ case BASE_DECIMAL: {
+ set_base_dialog->radiogroup_output->setButton(2);
+ break;
+ }
+ case BASE_HEXADECIMAL: {
+ set_base_dialog->radiogroup_output->setButton(3);
+ break;
+ }
+ case BASE_SEXAGESIMAL: {
+ set_base_dialog->radiogroup_output->setButton(5);
+ break;
+ }
+ case BASE_TIME: {
+ set_base_dialog->radiogroup_output->setButton(6);
+ break;
+ }
+ case BASE_ROMAN_NUMERALS: {
+ set_base_dialog->radiogroup_output->setButton(7);
+ break;
+ }
+ default: {
+ set_base_dialog->radiogroup_output->setButton(4);
+ set_base_dialog->outputBaseBox->setEnabled(true);
+ set_base_dialog->outputBaseBox->setValue(printops.base);
+ }
+ }
+ set_base_dialog->outputBaseBox->blockSignals(false);
+ set_base_dialog->radiogroup_output->blockSignals(false);
+ }
+}
+void KQalculate::numberBaseBinary() {
+ kpBaseCombo->blockSignals(true);
+ printops.base = BASE_BINARY;
+ updateBaseOther();
+ result_format_updated();
+ kpBaseCombo->setCurrentItem(0);
+ kpBaseCombo->blockSignals(false);
+}
+void KQalculate::numberBaseOctal() {
+ kpBaseCombo->blockSignals(true);
+ printops.base = BASE_OCTAL;
+ updateBaseOther();
+ result_format_updated();
+ kpBaseCombo->setCurrentItem(1);
+ kpBaseCombo->blockSignals(false);
+}
+void KQalculate::numberBaseDecimal() {
+ kpBaseCombo->blockSignals(true);
+ printops.base = BASE_DECIMAL;
+ updateBaseOther();
+ result_format_updated();
+ kpBaseCombo->setCurrentItem(2);
+ kpBaseCombo->blockSignals(false);
+}
+void KQalculate::numberBaseHexadecimal() {
+ kpBaseCombo->blockSignals(true);
+ printops.base = BASE_HEXADECIMAL;
+ updateBaseOther();
+ result_format_updated();
+ kpBaseCombo->setCurrentItem(3);
+ kpBaseCombo->blockSignals(false);
+}
+void KQalculate::numberBaseSexagesimal() {
+ kpBaseCombo->blockSignals(true);
+ printops.base = BASE_SEXAGESIMAL;
+ updateBaseOther();
+ result_format_updated();
+ kpBaseCombo->setCurrentItem(4);
+ kpBaseCombo->blockSignals(false);
+}
+void KQalculate::numberBaseTimeFormat() {
+ kpBaseCombo->blockSignals(true);
+ printops.base = BASE_TIME;
+ updateBaseOther();
+ result_format_updated();
+ kpBaseCombo->setCurrentItem(5);
+ kpBaseCombo->blockSignals(false);
+}
+void KQalculate::numberBaseRomanNumerals() {
+ kpBaseCombo->blockSignals(true);
+ printops.base = BASE_ROMAN_NUMERALS;
+ updateBaseOther();
+ result_format_updated();
+ kpBaseCombo->setCurrentItem(6);
+ kpBaseCombo->blockSignals(false);
+}
+void KQalculate::numberBaseOther() {
+ setBase();
+ set_base_dialog->radiogroup_output->setButton(4);
+ setBaseInResultFromDialogGroup(4);
+ set_base_dialog->outputBaseBox->setFocus();
+ setBaseInResultFromDialogBox(set_base_dialog->outputBaseBox->value());
+}
+
+void KQalculate::setBaseInExpressionFromDialogBox(int value) {
+ evalops.parse_options.base = value;
+ expression_format_updated(true);
+}
+void KQalculate::setBaseInExpressionFromDialogGroup(int id) {
+ switch(id) {
+ case 0: {
+ set_base_dialog->inputBaseBox->setEnabled(false);
+ evalops.parse_options.base = BASE_BINARY;
+ break;
+ }
+ case 1: {
+ set_base_dialog->inputBaseBox->setEnabled(false);
+ evalops.parse_options.base = BASE_OCTAL;
+ break;
+ }
+ case 2: {
+ set_base_dialog->inputBaseBox->setEnabled(false);
+ evalops.parse_options.base = BASE_DECIMAL;
+ break;
+ }
+ case 3: {
+ set_base_dialog->inputBaseBox->setEnabled(false);
+ evalops.parse_options.base = BASE_HEXADECIMAL;
+ break;
+ }
+ case 4: {
+ set_base_dialog->inputBaseBox->setEnabled(true);
+ evalops.parse_options.base = set_base_dialog->inputBaseBox->value();
+ break;
+ }
+ case 5: {
+ set_base_dialog->inputBaseBox->setEnabled(false);
+ evalops.parse_options.base = BASE_ROMAN_NUMERALS;
+ break;
+ }
+ }
+ expression_format_updated(true);
+}
+void KQalculate::setBaseInResultFromDialogBox(int value) {
+ bool b = (printops.base == value);
+ printops.base = value;
+ kpBaseCombo->blockSignals(true);
+ switch(value) {
+ case BASE_BINARY: {
+ ActionNumberBaseBinary->setChecked(true);
+ kpBaseCombo->setCurrentItem(0);
+ break;
+ }
+ case BASE_OCTAL: {
+ ActionNumberBaseOctal->setChecked(true);
+ kpBaseCombo->setCurrentItem(1);
+ break;
+ }
+ case BASE_DECIMAL: {
+ ActionNumberBaseDecimal->setChecked(true);
+ kpBaseCombo->setCurrentItem(2);
+ break;
+ }
+ case BASE_HEXADECIMAL: {
+ ActionNumberBaseHexadecimal->setChecked(true);
+ kpBaseCombo->setCurrentItem(3);
+ break;
+ }
+ default: {
+ ActionNumberBaseOther->setChecked(true);
+ kpBaseCombo->setCurrentItem(7);
+ break;
+ }
+ }
+ kpBaseCombo->blockSignals(false);
+ if(!b) result_format_updated();
+}
+void KQalculate::setBaseInResultFromDialogGroup(int id) {
+ switch(id) {
+ case 0: {
+ set_base_dialog->outputBaseBox->setEnabled(false);
+ ActionNumberBaseBinary->activate();
+ break;
+ }
+ case 1: {
+ set_base_dialog->outputBaseBox->setEnabled(false);
+ ActionNumberBaseOctal->activate();
+ break;
+ }
+ case 2: {
+ set_base_dialog->outputBaseBox->setEnabled(false);
+ ActionNumberBaseDecimal->activate();
+ break;
+ }
+ case 3: {
+ set_base_dialog->outputBaseBox->setEnabled(false);
+ ActionNumberBaseHexadecimal->activate();
+ break;
+ }
+ case 4: {
+ set_base_dialog->outputBaseBox->setEnabled(true);
+ ActionNumberBaseOther->setChecked(true);
+ kpBaseCombo->blockSignals(true);
+ bool b = (printops.base == set_base_dialog->outputBaseBox->value());
+ printops.base = set_base_dialog->outputBaseBox->value();
+ kpBaseCombo->setCurrentItem(7);
+ kpBaseCombo->blockSignals(false);
+ if(!b) result_format_updated();
+ break;
+ }
+ case 5: {
+ set_base_dialog->outputBaseBox->setEnabled(false);
+ ActionNumberBaseSexagesimal->activate();
+ break;
+ }
+ case 6: {
+ set_base_dialog->outputBaseBox->setEnabled(false);
+ ActionNumberBaseTimeFormat->activate();
+ break;
+ }
+ case 7: {
+ set_base_dialog->outputBaseBox->setEnabled(false);
+ ActionNumberBaseRomanNumerals->activate();
+ break;
+ }
+ }
+}
+void KQalculate::setBase() {
+ if(!set_base_dialog) {
+ set_base_dialog = new QalculateSetBaseDialog(this);
+ QObject::connect(set_base_dialog->radiogroup_input, SIGNAL(clicked(int)), this, SLOT(setBaseInExpressionFromDialogGroup(int)));
+ QObject::connect(set_base_dialog->inputBaseBox, SIGNAL(valueChanged(int)), this, SLOT(setBaseInExpressionFromDialogBox(int)));
+ QObject::connect(set_base_dialog->radiogroup_output, SIGNAL(clicked(int)), this, SLOT(setBaseInResultFromDialogGroup(int)));
+ QObject::connect(set_base_dialog->outputBaseBox, SIGNAL(valueChanged(int)), this, SLOT(setBaseInResultFromDialogBox(int)));
+ }
+ set_base_dialog->inputBaseBox->blockSignals(true);
+ set_base_dialog->radiogroup_input->blockSignals(true);
+ set_base_dialog->inputBaseBox->setEnabled(false);
+ switch(evalops.parse_options.base) {
+ case BASE_BINARY: {
+ set_base_dialog->radiogroup_input->setButton(0);
+ break;
+ }
+ case BASE_OCTAL: {
+ set_base_dialog->radiogroup_input->setButton(1);
+ break;
+ }
+ case BASE_DECIMAL: {
+ set_base_dialog->radiogroup_input->setButton(2);
+ break;
+ }
+ case BASE_HEXADECIMAL: {
+ set_base_dialog->radiogroup_input->setButton(3);
+ break;
+ }
+ case BASE_ROMAN_NUMERALS: {
+ set_base_dialog->radiogroup_input->setButton(5);
+ break;
+ }
+ default: {
+ set_base_dialog->radiogroup_input->setButton(4);
+ set_base_dialog->inputBaseBox->setEnabled(true);
+ set_base_dialog->inputBaseBox->setValue(evalops.parse_options.base);
+ }
+ }
+ set_base_dialog->inputBaseBox->blockSignals(false);
+ set_base_dialog->radiogroup_input->blockSignals(false);
+ updateBaseOther();
+ set_base_dialog->show();
+}
+
+void KQalculate::nonZeroDenominators(bool b) {
+ evalops.assume_denominators_nonzero = b;
+ expression_calculation_updated();
+}
+void KQalculate::warnAboutDenominatorsAssumedNonZero(bool b) {
+ evalops.warn_about_denominators_assumed_nonzero = b;
+ if(evalops.warn_about_denominators_assumed_nonzero) expression_calculation_updated();
+}
+
+void KQalculate::readPrecision(bool b) {
+ if(b) evalops.parse_options.read_precision = READ_PRECISION_WHEN_DECIMALS;
+ else evalops.parse_options.read_precision = DONT_READ_PRECISION;
+ expression_format_updated(true);
+}
+
+void KQalculate::limitImplicitMultiplication(bool b) {
+ evalops.parse_options.limit_implicit_multiplication = b;
+ printops.limit_implicit_multiplication = b;
+ expression_format_updated(true);
+ result_format_updated();
+}
+
+void KQalculate::rpnMode(bool b) {
+ if(b == rpn_mode) return;
+ rpn_mode = b;
+ if(rpn_mode) {
+ stackButton->show();
+ show_history = historyButton->isOn();
+ show_keypad = keypadButton->isOn();
+ if(show_stack) {
+ stackButton->toggle();
+ }
+ } else {
+ show_stack = stackButton->isOn();
+ if(show_stack) {
+ if(show_history) historyButton->toggle();
+ else if(show_keypad) keypadButton->toggle();
+ else stackButton->toggle();
+ }
+ stackButton->hide();
+ CALCULATOR->clearRPNStack();
+ stackList->clear();
+ }
+ if(leftButtonsSeparator->isVisible()) {
+ if(rpn_mode) executeButton->setText(i18n("Enter"));
+ else executeButton->setText(i18n("="));
+ }
+ if(rpn_mode) {
+ kpEquals->setText(i18n("Ent"));
+ QToolTip::add(kpEquals, i18n("Calculate expression and add to stack"));
+ QToolTip::add(executeButton, i18n("Calculate expression and add to stack"));
+ } else {
+ kpEquals->setText(i18n("="));
+ QToolTip::add(kpEquals, i18n("Calculate expression"));
+ QToolTip::add(executeButton, i18n("Calculate expression"));
+ }
+}
+
+void KQalculate::rpnSyntax(bool b) {
+ evalops.parse_options.rpn = b;
+ expression_format_updated(false);
+}
+
+void KQalculate::setMinDecimals(int i) {
+ printops.min_decimals = i;
+ if(i <= 0) printops.use_min_decimals = false;
+ else printops.use_min_decimals = true;
+ result_format_updated();
+}
+void KQalculate::setMaxDecimals(int i) {
+ printops.max_decimals = i;
+ if(i < 0) printops.use_max_decimals = false;
+ else printops.use_max_decimals = true;
+ result_format_updated();
+}
+
+void KQalculate::decimals() {
+ if(!decimalsDialog) {
+ decimalsDialog = new QalculateDecimalsDialog(this);
+ QObject::connect(decimalsDialog->minDecimalsBox, SIGNAL(valueChanged(int)), this, SLOT(setMinDecimals(int)));
+ QObject::connect(decimalsDialog->maxDecimalsBox, SIGNAL(valueChanged(int)), this, SLOT(setMaxDecimals(int)));
+ }
+ decimalsDialog->minDecimalsBox->blockSignals(true);
+ decimalsDialog->maxDecimalsBox->blockSignals(true);
+ if(printops.use_min_decimals && printops.min_decimals > 0) decimalsDialog->minDecimalsBox->setValue(printops.min_decimals);
+ else decimalsDialog->minDecimalsBox->setValue(0);
+ if(printops.use_max_decimals && printops.max_decimals >= 0) decimalsDialog->maxDecimalsBox->setValue(printops.max_decimals);
+ else decimalsDialog->maxDecimalsBox->setValue(-1);
+ decimalsDialog->minDecimalsBox->blockSignals(false);
+ decimalsDialog->maxDecimalsBox->blockSignals(false);
+ decimalsDialog->show();
+}
+
+void KQalculate::setPrecision(int i) {
+ if(i != CALCULATOR->getPrecision()) CALCULATOR->setPrecision(i);
+}
+void KQalculate::precision() {
+ if(!precisionDialog) {
+ precisionDialog = new QalculatePrecisionDialog(this);
+ QObject::connect(precisionDialog, SIGNAL(applyClicked()), this, SLOT(precisionRecalculate()));
+ QObject::connect(precisionDialog->precisionBox, SIGNAL(valueChanged(int)), this, SLOT(setPrecision(int)));
+ }
+ precisionDialog->precisionBox->setValue(CALCULATOR->getPrecision());
+ precisionDialog->show();
+}
+
+void KQalculate::precisionRecalculate() {
+ if(precisionDialog->precisionBox->value() != CALCULATOR->getPrecision()) CALCULATOR->setPrecision(precisionDialog->precisionBox->value());
+ expression_calculation_updated();
+}
+
+void KQalculate::assumptionTypeUnknown() {
+ CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_NONE);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+void KQalculate::assumptionTypeNonMatrix() {
+ CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_NONMATRIX);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+void KQalculate::assumptionTypeNumber() {
+ CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_NUMBER);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+void KQalculate::assumptionTypeComplex() {
+ CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_COMPLEX);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+void KQalculate::assumptionTypeReal() {
+ CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_REAL);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+void KQalculate::assumptionTypeRational() {
+ CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_RATIONAL);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+void KQalculate::assumptionTypeInteger() {
+ CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_INTEGER);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+
+void KQalculate::assumptionSignUnknown() {
+ CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_UNKNOWN);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+void KQalculate::assumptionSignNonZero() {
+ CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_NONZERO);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+void KQalculate::assumptionSignPositive() {
+ CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_POSITIVE);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+void KQalculate::assumptionSignNonNegative() {
+ CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_NONNEGATIVE);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+void KQalculate::assumptionSignNegative() {
+ CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_NEGATIVE);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+void KQalculate::assumptionSignNonPositive() {
+ CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_NONPOSITIVE);
+ setAssumptionsMenu();
+ expression_calculation_updated();
+}
+
+void KQalculate::algebraicModeSimplify() {
+ evalops.structuring = STRUCTURING_SIMPLIFY;
+ printops.allow_factorization = false;
+ expression_calculation_updated();
+}
+void KQalculate::algebraicModeFactorize() {
+ evalops.structuring = STRUCTURING_FACTORIZE;
+ printops.allow_factorization = true;
+ expression_calculation_updated();
+}
+void KQalculate::algebraicModeNone() {
+ evalops.structuring = STRUCTURING_NONE;
+ printops.allow_factorization = false;
+ expression_calculation_updated();
+}
+
+void KQalculate::onModesMenuItemActivated(int id) {
+ loadMode(menu_modes->indexOf(id));
+}
+void KQalculate::loadMode(int index) {
+ if(index < 0) return;
+ size_t i = (size_t) index;
+ if(i >= modes.size()) return;
+ printops.min_decimals = modes[i].po.min_decimals;
+ printops.use_min_decimals = modes[i].po.use_min_decimals;
+ printops.max_decimals = modes[i].po.max_decimals;
+ printops.use_max_decimals = modes[i].po.use_max_decimals;
+ CALCULATOR->setPrecision(modes[i].precision);
+ printops.min_exp = modes[i].po.min_exp;
+ printops.negative_exponents = modes[i].po.negative_exponents;
+ printops.sort_options.minus_last = modes[i].po.sort_options.minus_last;
+ printops.number_fraction_format = modes[i].po.number_fraction_format;
+ printops.use_unit_prefixes = modes[i].po.use_unit_prefixes;
+ printops.abbreviate_names = modes[i].po.abbreviate_names;
+ printops.use_all_prefixes = modes[i].po.use_all_prefixes;
+ printops.use_denominator_prefix = modes[i].po.use_denominator_prefix;
+ printops.place_units_separately = modes[i].po.place_units_separately;
+ evalops.auto_post_conversion = modes[i].eo.auto_post_conversion;
+ printops.base = modes[i].po.base;
+ evalops.parse_options.base = modes[i].eo.parse_options.base;
+ evalops.parse_options.read_precision = modes[i].eo.parse_options.read_precision;
+ evalops.assume_denominators_nonzero = modes[i].eo.assume_denominators_nonzero;
+ evalops.warn_about_denominators_assumed_nonzero = modes[i].eo.warn_about_denominators_assumed_nonzero;
+ evalops.parse_options.angle_unit = modes[i].eo.parse_options.angle_unit;
+ evalops.parse_options.functions_enabled = modes[i].eo.parse_options.functions_enabled;
+ evalops.parse_options.variables_enabled = modes[i].eo.parse_options.variables_enabled;
+ evalops.calculate_functions = modes[i].eo.calculate_functions;
+ evalops.calculate_variables = modes[i].eo.calculate_variables;
+ evalops.sync_units = modes[i].eo.sync_units;
+ evalops.parse_options.unknowns_enabled = modes[i].eo.parse_options.unknowns_enabled;
+ evalops.parse_options.units_enabled = modes[i].eo.parse_options.units_enabled;
+ evalops.allow_complex = modes[i].eo.allow_complex;
+ evalops.allow_infinite = modes[i].eo.allow_infinite;
+ evalops.structuring = modes[i].eo.structuring;
+ printops.indicate_infinite_series = modes[i].po.indicate_infinite_series;
+ printops.show_ending_zeroes = modes[i].po.show_ending_zeroes;
+ printops.round_halfway_to_even = modes[i].po.round_halfway_to_even;
+ evalops.approximation = modes[i].eo.approximation;
+ evalops.parse_options.rpn = modes[i].eo.parse_options.rpn;
+ evalops.parse_options.limit_implicit_multiplication = modes[i].eo.parse_options.limit_implicit_multiplication;
+ printops.limit_implicit_multiplication = modes[i].po.limit_implicit_multiplication;
+ printops.spacious = modes[i].po.spacious;
+ printops.excessive_parenthesis = modes[i].po.excessive_parenthesis;
+ printops.short_multiplication = modes[i].po.short_multiplication;
+ CALCULATOR->defaultAssumptions()->setType(modes[i].at);
+ CALCULATOR->defaultAssumptions()->setSign(modes[i].as);
+ if(modes[i].rpn_mode != rpn_mode) {
+ rpnMode(modes[i].rpn_mode);
+ }
+
+ setModeActions();
+
+ if(decimalsDialog) {
+ decimalsDialog->minDecimalsBox->blockSignals(true);
+ decimalsDialog->maxDecimalsBox->blockSignals(true);
+ if(printops.use_min_decimals && printops.min_decimals > 0) decimalsDialog->minDecimalsBox->setValue(printops.min_decimals);
+ else decimalsDialog->minDecimalsBox->setValue(0);
+ if(printops.use_max_decimals && printops.max_decimals >= 0) decimalsDialog->maxDecimalsBox->setValue(printops.max_decimals);
+ else decimalsDialog->maxDecimalsBox->setValue(-1);
+ decimalsDialog->minDecimalsBox->blockSignals(false);
+ decimalsDialog->maxDecimalsBox->blockSignals(false);
+ }
+ if(precisionDialog) {
+ precisionDialog->precisionBox->setValue(CALCULATOR->getPrecision());
+ }
+ updateBaseOther();
+ if(set_base_dialog) {
+ set_base_dialog->inputBaseBox->blockSignals(true);
+ set_base_dialog->radiogroup_input->blockSignals(true);
+ set_base_dialog->inputBaseBox->setEnabled(false);
+ switch(evalops.parse_options.base) {
+ case BASE_BINARY: {
+ set_base_dialog->radiogroup_input->setButton(0);
+ break;
+ }
+ case BASE_OCTAL: {
+ set_base_dialog->radiogroup_input->setButton(1);
+ break;
+ }
+ case BASE_DECIMAL: {
+ set_base_dialog->radiogroup_input->setButton(2);
+ break;
+ }
+ case BASE_HEXADECIMAL: {
+ set_base_dialog->radiogroup_input->setButton(3);
+ break;
+ }
+ case BASE_ROMAN_NUMERALS: {
+ set_base_dialog->radiogroup_input->setButton(5);
+ break;
+ }
+ default: {
+ set_base_dialog->radiogroup_input->setButton(4);
+ set_base_dialog->inputBaseBox->setEnabled(true);
+ set_base_dialog->inputBaseBox->setValue(evalops.parse_options.base);
+ }
+ }
+ set_base_dialog->inputBaseBox->blockSignals(false);
+ set_base_dialog->radiogroup_input->blockSignals(false);
+ }
+
+ update_status_text();
+ printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
+ QString str = expressionEdit->text().stripWhiteSpace();
+ if(expression_has_changed || str.isEmpty()) {
+ setResult(NULL, true, false, false);
+ } else {
+ execute_expression(false);
+ }
+
+ expression_has_changed2 = true;
+ displayParseStatus();
+ expressionEdit->setFocus();
+}
+QalculateModeDialog::QalculateModeDialog(QWidget *parent) : KDialogBase(parent, 0, true, i18n("Save Mode"), KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok, true) {
+ setMainWidget(new QWidget(this));
+ QGridLayout *grid = new QGridLayout(mainWidget(), 2, 2, 0, spacingHint());
+ grid->addWidget(new QLabel(i18n("Mode name:"), mainWidget()), 0, 0);
+ modeCombo = new KComboBox(mainWidget());
+ modeCombo->setEditable(true);
+ for(size_t i = 2; i < modes.size(); i++) {
+ modeCombo->insertItem(modes[i].name);
+ }
+ modeCombo->lineEdit()->clear();
+ modeCombo->setFocus();
+ modeCombo->setSizePolicy(QSizePolicy::Expanding, modeCombo->sizePolicy().verData());
+ grid->addWidget(modeCombo, 0, 1);
+ grid->addWidget(new QLabel(i18n("Shortcut:"), mainWidget()), 1, 0);
+ keyButton = new KKeyButton(mainWidget());
+ grid->addWidget(keyButton, 1, 1);
+
+ connect(keyButton, SIGNAL(capturedShortcut(const KShortcut&)), this, SLOT(updateShortcut(const KShortcut&)));
+ connect(modeCombo, SIGNAL(activated(int)), this, SLOT(modeSelected(int)));
+
+}
+QalculateModeDialog::~QalculateModeDialog() {}
+void QalculateModeDialog::modeSelected(int index) {
+ index += 2;
+ if(index < (int) modes.size()) {
+ keyButton->setShortcut(modes[index].shortcut, false);
+ }
+}
+void QalculateModeDialog::updateShortcut(const KShortcut &shortcut) {
+ keyButton->setShortcut(shortcut, false);
+}
+QString QalculateModeDialog::modeName() {
+ return modeCombo->currentText();
+}
+const KShortcut &QalculateModeDialog::modeShortcut() {
+ return keyButton->shortcut();
+}
+void QalculateModeDialog::slotOk() {
+ QString name = modeName();
+ if(name.isEmpty()) {
+ KMessageBox::error(this, i18n("Empty mode name."));
+ return;
+ } else if(name == modes[0].name) {
+ KMessageBox::error(this, i18n("Preset mode cannot be overwritten."));
+ return;
+ }
+ KDialogBase::slotOk();
+}
+void KQalculate::saveModeAs() {
+ QalculateModeDialog *dialog = new QalculateModeDialog(this);
+ if(dialog->exec() == QDialog::Accepted) {
+ bool new_mode = true;
+ QString name = dialog->modeName().stripWhiteSpace();
+ size_t index = save_mode_as(name, &new_mode);
+ modes[index].shortcut = dialog->modeShortcut();
+ if(new_mode) {
+ menu_modes->insertItem(modes[index].name, -1, index);
+ ActionDeleteMode->setEnabled(true);
+ ModeObject *mo = new ModeObject(index);
+ mo->i_mode = index;
+ mode_objects.push_back(mo);
+ 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()));
+ } else {
+ accel()->setShortcut(QString("Load mode: ") + modes[index].name, modes[index].shortcut);
+ }
+ }
+ delete dialog;
+}
+void KQalculate::deleteMode() {
+#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 2
+ bool b_ok = false;
+ QStringList mode_names;
+ for(size_t i = 2; i < modes.size(); i++) {
+ mode_names += modes[i].name;
+ }
+ QString name = KInputDialog::getItem(i18n("Delete Mode"), i18n("Mode:"), mode_names, 0, false, &b_ok, this).stripWhiteSpace();
+ if(b_ok) {
+ for(size_t i = 2; i < modes.size(); i++) {
+ if(modes[i].name == name) {
+ accel()->remove(QString("Load mode: ") + name);
+ modes.erase(modes.begin() + i);
+ delete mode_objects[i - 2];
+ mode_objects.erase(mode_objects.begin() + (i - 2));
+ for(QValueVector<ModeObject*>::size_type i2 = 0; i2 < mode_objects.size(); i2++) {
+ mode_objects[i2]->i_mode = i2 + 2;
+ }
+ menu_modes->removeItemAt(i);
+ if(modes.size() < 3) {
+ ActionDeleteMode->setEnabled(false);
+ }
+ }
+ }
+ }
+#endif
+}
+void KQalculate::saveMode() {
+ save_mode();
+}
+
+void KQalculate::aboutToQuit() {
+ if(plot_dialog) plot_dialog->saveMode();
+ if(save_mode_on_exit) {
+ save_mode();
+ } else {
+ save_preferences();
+ }
+ if(save_defs_on_exit) {
+ save_defs();
+ }
+ pthread_cancel(view_thread);
+ CALCULATOR->terminateThreads();
+}
+
+void KQalculate::angleUnitDegrees() {
+ kpAngleGroup->blockSignals(true);
+ evalops.parse_options.angle_unit = ANGLE_UNIT_DEGREES;
+ expression_format_updated(true);
+ kpAngleGroup->setButton(0);
+ kpAngleGroup->blockSignals(false);
+}
+void KQalculate::angleUnitRadians() {
+ kpAngleGroup->blockSignals(true);
+ evalops.parse_options.angle_unit = ANGLE_UNIT_RADIANS;
+ expression_format_updated(true);
+ kpAngleGroup->setButton(1);
+ kpAngleGroup->blockSignals(false);
+}
+void KQalculate::angleUnitGradians() {
+ kpAngleGroup->blockSignals(true);
+ evalops.parse_options.angle_unit = ANGLE_UNIT_GRADIANS;
+ expression_format_updated(true);
+ kpAngleGroup->setButton(2);
+ kpAngleGroup->blockSignals(false);
+}
+void KQalculate::angleUnitNone() {
+ kpAngleGroup->blockSignals(true);
+ evalops.parse_options.angle_unit = ANGLE_UNIT_NONE;
+ expression_format_updated(true);
+ kpAngleGroup->setButton(3);
+ kpAngleGroup->blockSignals(false);
+}
+
+void KQalculate::placeUnitsSeparately(bool b) {
+ printops.place_units_separately = b;
+ result_format_updated();
+}
+
+
+void KQalculate::enableDenominatorPrefixes(bool b) {
+ printops.use_denominator_prefix = b;
+ result_format_updated();
+}
+
+
+void KQalculate::enableUseOfAllPrefixes(bool b) {
+ printops.use_all_prefixes = b;
+ result_format_updated();
+}
+
+
+void KQalculate::enablePrefixes(bool b) {
+ printops.use_unit_prefixes = b;
+ result_format_updated();
+}
+
+void KQalculate::autoNoConversion() {
+ evalops.auto_post_conversion = POST_CONVERSION_NONE;
+ expression_calculation_updated();
+}
+void KQalculate::autoConvertToBaseUnits() {
+ evalops.auto_post_conversion = POST_CONVERSION_BASE;
+ expression_calculation_updated();
+}
+void KQalculate::autoConvertToBestUnit() {
+ evalops.auto_post_conversion = POST_CONVERSION_BEST;
+ expression_calculation_updated();
+}
+
+void KQalculate::allowInfiniteResult(bool b) {
+ evalops.allow_infinite = b;
+ expression_calculation_updated();
+}
+
+
+void KQalculate::allowComplexResult(bool b) {
+ evalops.allow_complex = b;
+ expression_calculation_updated();
+}
+
+
+void KQalculate::calculateVariables(bool b) {
+ evalops.calculate_variables = b;
+ expression_calculation_updated();
+}
+
+
+void KQalculate::enableUnknowns(bool b) {
+ evalops.parse_options.unknowns_enabled = b;
+ expression_format_updated(b);
+}
+
+
+void KQalculate::enableUnits(bool b) {
+ evalops.parse_options.units_enabled = b;
+ expression_format_updated(b);
+}
+
+
+void KQalculate::enableFunctions(bool b) {
+ evalops.parse_options.functions_enabled = b;
+ expression_format_updated(b);
+}
+
+
+void KQalculate::enableVariables(bool b) {
+ evalops.parse_options.variables_enabled = b;
+ expression_format_updated(b);
+}
+
+void KQalculate::updateExchangeRates() {
+ if(fetch_exchange_rates(15)) {
+ CALCULATOR->loadExchangeRates();
+ }
+ expression_calculation_updated();
+}
+
+void KQalculate::insertRaise() {
+ if(rpn_mode) {
+ calculateRPN(OPERATION_RAISE);
+ return;
+ }
+ if(!evalops.parse_options.rpn) {
+ expressionEdit->wrapSelection();
+ expressionEdit->deselect();
+ }
+ insert_text("^");
+}
+
+
+void KQalculate::insertLn() {
+ insertButtonFunction(CALCULATOR->f_ln);
+}
+
+
+void KQalculate::insertLog() {
+ MathFunction *f = CALCULATOR->getActiveFunction("log10");
+ if(f) {
+ insertButtonFunction(f);
+ } else {
+ KMessageBox::error(this, i18n("log10 function not found."));
+ }
+}
+
+
+void KQalculate::insertSqrt() {
+ insertButtonFunction(CALCULATOR->f_sqrt);
+}
+
+
+void KQalculate::insertTan() {
+ if(kpHyp->isOn()) {
+ if(kpInv->isOn()) {
+ insertButtonFunction(CALCULATOR->f_atanh);
+ } else {
+ insertButtonFunction(CALCULATOR->f_tanh);
+ }
+ } else {
+ if(kpInv->isOn()) {
+ insertButtonFunction(CALCULATOR->f_atan);
+ } else {
+ insertButtonFunction(CALCULATOR->f_tan);
+ }
+ }
+}
+
+
+void KQalculate::insertSin() {
+ if(kpHyp->isOn()) {
+ kpHyp->setOn(false);
+ if(kpInv->isOn()) {
+ kpInv->setOn(false);
+ insertButtonFunction(CALCULATOR->f_asinh);
+ } else {
+ insertButtonFunction(CALCULATOR->f_sinh);
+ }
+ } else {
+ if(kpInv->isOn()) {
+ kpInv->setOn(false);
+ insertButtonFunction(CALCULATOR->f_asin);
+ } else {
+ insertButtonFunction(CALCULATOR->f_sin);
+ }
+ }
+}
+
+
+void KQalculate::insertCos() {
+ if(kpHyp->isOn()) {
+ kpHyp->setOn(false);
+ if(kpInv->isOn()) {
+ kpInv->setOn(false);
+ insertButtonFunction(CALCULATOR->f_acosh);
+ } else {
+ insertButtonFunction(CALCULATOR->f_cosh);
+ }
+ } else {
+ if(kpInv->isOn()) {
+ kpInv->setOn(false);
+ insertButtonFunction(CALCULATOR->f_acos);
+ } else {
+ insertButtonFunction(CALCULATOR->f_cos);
+ }
+ }
+}
+
+
+void KQalculate::insertDivision() {
+ if(rpn_mode) {
+ calculateRPN(OPERATION_DIVIDE);
+ return;
+ }
+ if(!evalops.parse_options.rpn) {
+ expressionEdit->wrapSelection();
+ expressionEdit->deselect();
+ }
+ if(printops.use_unicode_signs && printops.division_sign == DIVISION_SIGN_DIVISION && can_display_unicode_string_function(SIGN_DIVISION, (void*) expressionEdit)) {
+ insert_text(SIGN_DIVISION);
+ } else {
+ insert_text("/");
+ }
+}
+
+
+void KQalculate::insertTimes() {
+ if(rpn_mode) {
+ calculateRPN(OPERATION_MULTIPLY);
+ return;
+ }
+ if(!evalops.parse_options.rpn) {
+ expressionEdit->wrapSelection();
+ expressionEdit->deselect();
+ }
+ if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_DOT && can_display_unicode_string_function(SIGN_MULTIDOT, (void*) expressionEdit)) {
+ insert_text(SIGN_MULTIDOT);
+ } else if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_DOT && can_display_unicode_string_function(SIGN_SMALLCIRCLE, (void*) expressionEdit)) {
+ insert_text(SIGN_SMALLCIRCLE);
+ } else if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_X && can_display_unicode_string_function(SIGN_MULTIPLICATION, (void*) expressionEdit)) {
+ insert_text(SIGN_MULTIPLICATION);
+ } else {
+ insert_text("*");
+ }
+}
+
+
+void KQalculate::calculateRPN(int op) {
+ if(expression_has_changed && !expressionEdit->text().stripWhiteSpace().isEmpty()) {
+ execute();
+ }
+ execute_expression_force = true;
+ execute_expression_do_stack = false;
+ execute_expression_do_mathoperation = true;
+ execute_expression_op = (MathOperation) op;
+ execute_expression_f = NULL;
+ execute_expression2();
+}
+void KQalculate::calculateRPN(MathFunction *f) {
+ if(expression_has_changed && !expressionEdit->text().stripWhiteSpace().isEmpty()) {
+ execute();
+ }
+ execute_expression_force = true;
+ execute_expression_do_stack = false;
+ execute_expression_do_mathoperation = true;
+ execute_expression_f = f;
+ execute_expression2();
+}
+void KQalculate::RPNStackEnter(Variable *v) {
+ CALCULATOR->RPNStackEnter(new MathStructure(v), true);
+ mstruct->unref();
+ mstruct = CALCULATOR->getRPNRegister(1);
+ mstruct->ref();
+ 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());
+}
+void KQalculate::RPNRegisterAdded(const QString &text, size_t index) {
+ if(index == 0) {
+ new KListViewItem(stackList, QString::number(index + 1), text);
+ } else {
+ new KListViewItem(stackList, getRPNRegister(index - 1), QString::number(index + 1), text);
+ }
+ updateRPNIndexes();
+ clearStackButton->setEnabled(true);
+}
+void KQalculate::RPNRegisterRemoved(size_t index) {
+ delete getRPNRegister(index);
+ updateRPNIndexes();
+ if(CALCULATOR->RPNStackSize() == 0) {
+ clearStackButton->setEnabled(false);
+ }
+}
+void KQalculate::RPNRegisterChanged(const QString &text, size_t index) {
+ getRPNRegister(index)->setText(1, text);
+}
+QListViewItem *KQalculate::getRPNRegister(size_t index) {
+ QListViewItem *li = stackList->firstChild();
+ while(li) {
+ if(index == 0) return li;
+ index--;
+ li = li->nextSibling();
+ }
+ return NULL;
+}
+void KQalculate::clearStack() {
+ CALCULATOR->clearRPNStack();
+ stackList->clear();
+ clearresult();
+ mstruct->clear();
+ clearStackButton->setEnabled(false);
+}
+void KQalculate::registerUp() {
+ QListViewItem *li = stackList->selectedItem();
+ if(li) {
+ size_t index = (size_t) li->text(0).toUInt() - 1;
+ if(index == 0) return;
+ CALCULATOR->moveRPNRegisterUp(index + 1);
+ QListViewItem *li2 = li->itemAbove();
+ QString str = li2->text(1);
+ li2->setText(1, li->text(1));
+ li->setText(1, str);
+ stackList->setSelected(li2, true);
+ if(index == 1) {
+ mstruct->unref();
+ mstruct = CALCULATOR->getRPNRegister(1);
+ mstruct->ref();
+ setResult(NULL, true, false, false, "", 0, true);
+ }
+ }
+}
+void KQalculate::registerDown() {
+ QListViewItem *li = stackList->selectedItem();
+ if(li) {
+ size_t index = (size_t) li->text(0).toUInt() - 1;
+ if(index + 1 == CALCULATOR->RPNStackSize()) return;
+ CALCULATOR->moveRPNRegisterDown(index + 1);
+ QListViewItem *li2 = li->nextSibling();
+ QString str = li2->text(1);
+ li2->setText(1, li->text(1));
+ li->setText(1, str);
+ stackList->setSelected(li2, true);
+ if(index == 0) {
+ mstruct->unref();
+ mstruct = CALCULATOR->getRPNRegister(1);
+ mstruct->ref();
+ setResult(NULL, true, false, false, "", 0, true);
+ }
+ }
+}
+void KQalculate::deleteRegister() {
+ QListViewItem *li = stackList->selectedItem();
+ if(li) {
+ size_t index = (size_t) li->text(0).toUInt() - 1;
+ CALCULATOR->deleteRPNRegister(index + 1);
+ delete li;
+ if(CALCULATOR->RPNStackSize() == 0) {
+ clearresult();
+ mstruct->clear();
+ clearStackButton->setEnabled(false);
+ } else if(index == 0) {
+ mstruct->unref();
+ mstruct = CALCULATOR->getRPNRegister(1);
+ mstruct->ref();
+ setResult(NULL, true, false, false, "", 0, true);
+ }
+ updateRPNIndexes();
+ }
+}
+void KQalculate::editRegister() {
+ QListViewItem *li = stackList->selectedItem();
+ if(!li) return;
+ stackList->rename(li, 1);
+}
+void KQalculate::updateRPNIndexes() {
+ QListViewItem *li = stackList->firstChild();
+ size_t i = 1;
+ while(li) {
+ li->setText(0, QString::number(i));
+ i++;
+ li = li->nextSibling();
+ }
+}
+void KQalculate::stackRegisterMoved() {
+ QListViewItem *li = stackList->firstChild();
+ size_t i = 0;
+ size_t old_index;
+ while(li) {
+ old_index = (size_t) li->text(0).toUInt() - 1;
+ if(old_index != i) {
+ CALCULATOR->moveRPNRegister(old_index + 1, i + 1);
+ if(i == 0) {
+ mstruct->unref();
+ mstruct = CALCULATOR->getRPNRegister(1);
+ mstruct->ref();
+ setResult(NULL, true, false, false, "", 0, true);
+ }
+ updateRPNIndexes();
+ registerSelected();
+ return;
+ }
+ i++;
+ li = li->nextSibling();
+ }
+}
+void KQalculate::stackRegisterSet(QListViewItem *li) {
+ execute_expression_stack_index = (size_t) li->text(0).toUInt() - 1;
+ execute_expression_force = true;
+ execute_expression_do_stack = true;
+ execute_expression_do_mathoperation = false;
+ execute_expression2();
+}
+void KQalculate::popupStackMenu(KListView*, QListViewItem *li, const QPoint &p) {
+ stackMenu->setItemEnabled(stackMenu->idAt(0), li != NULL);
+ stackMenu->setItemEnabled(stackMenu->idAt(1), li != NULL);
+ stackMenu->setItemEnabled(stackMenu->idAt(3), CALCULATOR->RPNStackSize() > 0);
+ stackMenu->popup(p);
+}
+void KQalculate::registerSelected() {
+ QListViewItem *li = stackList->selectedItem();
+ if(li) {
+ size_t index = (size_t) li->text(0).toUInt() - 1;
+ registerUpButton->setEnabled(index != 0);
+ registerDownButton->setEnabled(index + 1 < CALCULATOR->RPNStackSize());
+ editRegisterButton->setEnabled(true);
+ deleteRegisterButton->setEnabled(true);
+ } else {
+ registerUpButton->setEnabled(false);
+ registerDownButton->setEnabled(false);
+ editRegisterButton->setEnabled(false);
+ deleteRegisterButton->setEnabled(false);
+ }
+}
+
+void KQalculate::insertPlus() {
+ if(rpn_mode) {
+ calculateRPN(OPERATION_ADD);
+ return;
+ }
+ if(!evalops.parse_options.rpn) {
+ expressionEdit->wrapSelection();
+ expressionEdit->deselect();
+ }
+ insert_text("+");
+}
+
+void KQalculate::insertMinus() {
+ if(rpn_mode) {
+ calculateRPN(OPERATION_SUBTRACT);
+ return;
+ }
+ if(!evalops.parse_options.rpn) {
+ expressionEdit->wrapSelection();
+ expressionEdit->deselect();
+ }
+ if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_MINUS, (void*) expressionEdit)) insert_text(SIGN_MINUS);
+ else insert_text("-");
+}
+
+void KQalculate::insertAns() {
+ insert_text(vans[0]->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str());
+}
+
+
+void KQalculate::insertExp() {
+ if(rpn_mode) {
+ calculateRPN(OPERATION_EXP10);
+ return;
+ }
+ if(printops.lower_case_e) insert_text("e");
+ else insert_text("E");
+}
+
+
+void KQalculate::insertDot() {
+ insert_text(CALCULATOR->getDecimalPoint().c_str());
+}
+
+
+void KQalculate::insertKP0() {
+ insert_text("0");
+}
+
+
+void KQalculate::insertKP9() {
+ insert_text("9");
+}
+
+
+void KQalculate::insertKP8() {
+ insert_text("8");
+}
+
+
+void KQalculate::insertKP7() {
+ insert_text("7");
+}
+
+
+void KQalculate::insertKP6() {
+ insert_text("6");
+}
+
+
+void KQalculate::insertKP5() {
+ insert_text("5");
+}
+
+
+void KQalculate::insertKP4() {
+ insert_text("4");
+}
+
+
+void KQalculate::insertKP3() {
+ insert_text("3");
+}
+
+
+void KQalculate::insertKP2() {
+ insert_text("2");
+}
+
+
+void KQalculate::insertKP1() {
+ insert_text("1");
+}
+
+void KQalculate::expressionDel() {
+ expressionEdit->del();
+}
+
+
+void KQalculate::clearExpression() {
+ expressionEdit->clear();
+}
+
+void KQalculate::insertSquare() {
+ if(rpn_mode) {
+ calculateRPN(CALCULATOR->f_sq);
+ return;
+ }
+ if(evalops.parse_options.rpn) {
+ insertButtonFunction(CALCULATOR->f_sq);
+ } else {
+ expressionEdit->wrapSelection();
+ expressionEdit->deselect();
+ insert_text("^2");
+ }
+}
+
+void KQalculate::setFractionMode(bool b) {
+ if(b) {
+ ActionFractionalDisplayFraction->activate();
+ } else {
+ ActionFractionalDisplayDecimal->activate();
+ }
+}
+
+void KQalculate::setExactMode(bool b) {
+ if(b) {
+ ActionApproximationAlwaysExact->activate();
+ } else {
+ ActionApproximationTryExact->activate();
+ }
+}
+
+void KQalculate::kpSetAngleUnit(int index) {
+ switch(index) {
+ case 0: {
+ ActionAngleUnitDegrees->activate();
+ break;
+ }
+ case 1: {
+ ActionAngleUnitRadians->activate();
+ break;
+ }
+ case 2: {
+ ActionAngleUnitGradians->activate();
+ break;
+ }
+ case 3: {
+ ActionAngleUnitNone->activate();
+ break;
+ }
+ }
+}
+
+void KQalculate::kpSetNumericalMode(int index) {
+ switch(index) {
+ case 0: {
+ printops.negative_exponents = false;
+ printops.sort_options.minus_last = true;
+ ActionNumericalDisplayNormal->activate();
+ break;
+ }
+ case 1: {
+ ActionNumericalDisplayEngineering->activate();
+ break;
+ }
+ case 2: {
+ printops.negative_exponents = true;
+ printops.sort_options.minus_last = false;
+ ActionNumericalDisplayScientific->activate();
+ break;
+ }
+ case 3: {
+ printops.negative_exponents = true;
+ printops.sort_options.minus_last = false;
+ ActionNumericalDisplayPurelyScientific->activate();
+ break;
+ }
+ case 4: {
+ printops.negative_exponents = false;
+ printops.sort_options.minus_last = true;
+ ActionNumericalDisplaySimple->activate();
+ break;
+ }
+ }
+ ActionNegativeExponents->setChecked(printops.negative_exponents);
+ ActionSortMinusLast->setChecked(printops.sort_options.minus_last);
+}
+
+
+void KQalculate::kpSetBaseSelected(int index) {
+ switch(index) {
+ case 7: {
+ numberBaseOther();
+ break;
+ }
+ }
+}
+void KQalculate::kpSetBase(int index) {
+ switch(index) {
+ case 0: {
+ ActionNumberBaseBinary->activate();
+ break;
+ }
+ case 1: {
+ ActionNumberBaseOctal->activate();
+ break;
+ }
+ case 2: {
+ ActionNumberBaseDecimal->activate();
+ break;
+ }
+ case 3: {
+ ActionNumberBaseHexadecimal->activate();
+ break;
+ }
+ case 4: {
+ ActionNumberBaseSexagesimal->activate();
+ break;
+ }
+ case 5: {
+ ActionNumberBaseTimeFormat->activate();
+ break;
+ }
+ case 6: {
+ ActionNumberBaseRomanNumerals->activate();
+ break;
+ }
+ case 7: {
+ ActionNumberBaseOther->activate();
+ break;
+ }
+ }
+}
+
+void KQalculate::insertMod() {
+ insertButtonFunction(CALCULATOR->f_mod);
+}
+
+
+void KQalculate::insertFactorial() {
+ if(rpn_mode) {
+ insertButtonFunction(CALCULATOR->f_factorial);
+ return;
+ }
+ expressionEdit->wrapSelection();
+ expressionEdit->deselect();
+ insert_text("!");
+}
+
+void KQalculate::storeResult() {
+ if(!store_dialog) {
+ store_dialog = new QalculateEditVariableDialog(this);
+ }
+ Variable *v = store_dialog->editVariable(i18n("Temporary"), NULL, mstruct, true);
+ if(v) {
+ update_vmenu();
+ variable_inserted(v);
+ }
+}
+
+void KQalculate::manageVariables() {
+ if(!variables_dialog) {
+ variables_dialog = new QalculateVariablesDialog();
+ variables_dialog->updateVariableTree();
+ QObject::connect(variables_dialog, SIGNAL(variablesChanged()), this, SLOT(update_vmenu()));
+ QObject::connect(variables_dialog, SIGNAL(insertRequest(Variable*)), this, SLOT(insertVariable(Variable*)));
+ }
+ variables_dialog->show();
+}
+void KQalculate::insertVariable(Variable *v) {
+ insert_text(v->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str());
+ variable_inserted(v);
+}
+void KQalculate::insertFunction(MathFunction *f, QWidget *parent) {
+ if(!CALCULATOR->stillHasFunction(f)) {
+ KMessageBox::error(parent, i18n("Function does not exist anymore."));
+ update_fmenu();
+ return;
+ }
+ if(f->args() == 0) {
+ QString str = f->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str();
+ str += "()";
+ insert_text(str);
+ function_inserted(f);
+ } else {
+ QalculateInsertFunctionDialog *dialog = new QalculateInsertFunctionDialog(f, parent, expressionEdit->selectedText());
+ int rcode = dialog->exec();
+ if(rcode != QDialog::Rejected) {
+ if(rcode == QDialog::Accepted) {
+ insert_text(dialog->functionExpression());
+ } else {
+ expressionEdit->setText(dialog->functionExpression());
+ execute();
+ expressionEdit->setFocus();
+ }
+ function_inserted(f);
+ }
+ delete dialog;
+ }
+}
+void KQalculate::applyFunction(MathFunction *f, QWidget *parent) {
+ if(!CALCULATOR->stillHasFunction(f)) {
+ KMessageBox::error(parent, i18n("Function does not exist anymore."));
+ update_fmenu();
+ return;
+ }
+ if(rpn_mode) {
+ calculateRPN(f);
+ return;
+ }
+ QString str = f->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str();
+ if(f->args() == 0) {
+ str += "()";
+ } else {
+ str += "(";
+ str += vans[0]->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str();
+ str += ")";
+ }
+ insert_text(str);
+ function_inserted(f);
+ execute();
+}
+
+void KQalculate::convertToUnitConvertToDialogExpression() {
+ error_timer->stop();
+ mstruct->set(CALCULATOR->convert(*mstruct, convert_to_unit_expression_dialog->unitExpressionEdit->text().ascii(), evalops));
+ result_action_executed();
+ error_timer->start(100);
+}
+
+void KQalculate::convertToUnitExpression() {
+ if(!convert_to_unit_expression_dialog) {
+ convert_to_unit_expression_dialog = new QalculateConvertUnitsDialog(this);
+ convert_to_unit_expression_dialog->updateUnitTree();
+ QObject::connect(convert_to_unit_expression_dialog, SIGNAL(applyClicked()), this, SLOT(convertToUnitConvertToDialogExpression()));
+ QObject::connect(convert_to_unit_expression_dialog, SIGNAL(okClicked()), this, SLOT(convertToUnitConvertToDialogExpression()));
+ QObject::connect(convert_to_unit_expression_dialog, SIGNAL(unitsChanged()), this, SLOT(update_umenus()));
+ }
+ convert_to_unit_expression_dialog->show();
+}
+
+void KQalculate::convertNumberBases() {
+ if(!convert_number_bases_dialog) {
+ convert_number_bases_dialog = new QalculateConvertNumberBasesDialog();
+ }
+ convert_number_bases_dialog->show();
+}
+
+void KQalculate::insertManagedFunction(MathFunction *f) {
+ insertFunction(f, functions_dialog);
+}
+void KQalculate::applyManagedFunction(MathFunction *f) {
+ applyFunction(f, functions_dialog);
+}
+void KQalculate::manageFunctions() {
+ if(!functions_dialog) {
+ functions_dialog = new QalculateFunctionsDialog();
+ functions_dialog->updateFunctionTree();
+ QObject::connect(functions_dialog, SIGNAL(functionsChanged()), this, SLOT(update_fmenu()));
+ QObject::connect(functions_dialog, SIGNAL(insertRequest(MathFunction*)), this, SLOT(insertManagedFunction(MathFunction*)));
+ QObject::connect(functions_dialog, SIGNAL(applyRequest(MathFunction*)), this, SLOT(applyManagedFunction(MathFunction*)));
+ }
+ functions_dialog->show();
+}
+
+void KQalculate::newUnit() {
+ if(!unit_edit_dialog) {
+ unit_edit_dialog = new QalculateEditUnitDialog(this);
+ }
+ Unit *u = unit_edit_dialog->editUnit();
+ if(u) {
+ update_umenus();
+ unit_inserted(u);
+ }
+}
+
+
+void KQalculate::newDataSet() {
+ if(!dataset_edit_dialog) {
+ dataset_edit_dialog = new QalculateEditDataSetDialog(this);
+ }
+ MathFunction *f = dataset_edit_dialog->editDataSet();
+ if(f) {
+ update_fmenu();
+ function_inserted(f);
+ }
+}
+
+
+void KQalculate::newFunction() {
+ if(!function_edit_dialog) {
+ function_edit_dialog = new QalculateEditFunctionDialog(this);
+ }
+ MathFunction *f = function_edit_dialog->editFunction();
+ if(f) {
+ update_fmenu();
+ function_inserted(f);
+ }
+}
+
+
+void KQalculate::newUnknownVariable() {
+ if(!unknown_edit_dialog) {
+ unknown_edit_dialog = new QalculateEditUnknownVariableDialog(this);
+ }
+ Variable *v = unknown_edit_dialog->editVariable(i18n("My Variables"));
+ if(v) {
+ update_vmenu();
+ variable_inserted(v);
+ }
+}
+
+
+void KQalculate::newVector() {
+ if(!matrix_edit_dialog) {
+ matrix_edit_dialog = new QalculateEditMatrixVectorDialog(this);
+ }
+ Variable *v = matrix_edit_dialog->newVector(i18n("Vectors"));
+ if(v) {
+ update_vmenu();
+ variable_inserted(v);
+ }
+}
+
+
+void KQalculate::newMatrix() {
+ if(!matrix_edit_dialog) {
+ matrix_edit_dialog = new QalculateEditMatrixVectorDialog(this);
+ }
+ Variable *v = matrix_edit_dialog->newMatrix(i18n("Matrices"));
+ if(v) {
+ update_vmenu();
+ variable_inserted(v);
+ }
+}
+
+
+void KQalculate::newVariable() {
+ if(!variable_edit_dialog) {
+ variable_edit_dialog = new QalculateEditVariableDialog(false);
+ }
+ Variable *v = variable_edit_dialog->editVariable(i18n("My Variables"));
+ if(v) {
+ update_vmenu();
+ variable_inserted(v);
+ }
+}
+
+
+void KQalculate::exportCSVFile() {
+ if(!export_csv_dialog) {
+ export_csv_dialog = new QalculateExportCSVDialog(this);
+ }
+ export_csv_dialog->exportCSVFile();
+}
+
+
+void KQalculate::importCSVFile() {
+ if(!import_csv_dialog) {
+ import_csv_dialog = new QalculateImportCSVDialog(this);
+ }
+ if(import_csv_dialog->importCSVFile()) {
+ update_vmenu();
+ }
+}
+
+
+void KQalculate::saveAsImage() {
+ QString filename;
+ while(true) {
+ filename = KFileDialog::getSaveFileName("qalculate.png", "image/png", this, i18n("Save Image"));
+ if(filename.isEmpty()) {
+ return;
+ } else {
+ if(QFile::exists(filename)) {
+ 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) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ QString str = result_text;
+ str.replace("width=1 ", "");
+ QSimpleRichText text(str, resultLabel->font());
+ QPicture picture;
+ QPainter p(&picture);
+ text.setWidth(1000);
+ text.draw(&p, 0, 0, QRect(), QColorGroup(Qt::black, Qt::white, Qt::white, Qt::white, Qt::white, Qt::black, Qt::white));
+ p.flush();
+ p.end();
+ QPixmap pixmap(picture.boundingRect().width(), picture.boundingRect().height());
+ pixmap.fill(Qt::white);
+ QPainter p2(&pixmap);
+ p2.drawPicture(-picture.boundingRect().x(), -picture.boundingRect().y(), picture);
+ p2.flush();
+ p2.end();
+ QImage image(pixmap.convertToImage());
+ image.setAlphaBuffer(true);
+ int h = image.height(), w = image.width();
+ QRgb pixel;
+ for(int r =0; r < h; r++) {
+ for(int c =0; c < w; c++) {
+ pixel = image.pixel(c, r);
+ image.setPixel(c, r, qRgba(0, 0, 0, 0xff - ((qRed(pixel) + qBlue(pixel) + qGreen(pixel))/ 3)));
+ }
+ }
+ if(!image.save(filename, "PNG")) {
+ KMessageBox::error(this, i18n("Failed to save image."));
+ }
+}
+
+
+void KQalculate::saveDefinitions() {
+ save_defs();
+}
+
+
+void KQalculate::plotFunctionsData() {
+ if(!plot_dialog) {
+ plot_dialog = new QalculatePlotDialog();
+ }
+ plot_dialog->expressionEdit->setText(expressionEdit->text());
+ plot_dialog->show();
+}
+
+
+void KQalculate::periodicTable() {
+ if(!periodic_table_dialog) {
+ periodic_table_dialog = new QalculatePeriodicTableDialog();
+ }
+ periodic_table_dialog->show();
+}
+
+
+void KQalculate::onSetPrefixMenuItemActivated(int id) {
+ if(!menu_set_prefix_ids.contains(id)) return;
+ result_prefix_changed(menu_set_prefix_ids[id]);
+}
+
+
+void KQalculate::onConvertToUnitMenuItemActivated(int id) {
+ if(!menu_to_unit_ids.contains(id)) return;
+ error_timer->stop();
+ mstruct->set(CALCULATOR->convert(*mstruct, menu_to_unit_ids[id], evalops));
+ result_action_executed();
+ error_timer->start(100);
+}
+
+
+
+void KQalculate::preferences() {
+ if(!preferences_dialog) {
+ preferences_dialog = new QalculatePreferencesDialog(this);
+ }
+ close_to_systray_was = close_to_systray;
+ display_expression_status_was = display_expression_status;
+ preferences_dialog->editPreferences();
+}
+
+void KQalculate::applyPreferences() {
+ if(use_custom_result_font) {
+ QFont font(resultLabel->font());
+ font.fromString(custom_result_font);
+ resultLabel->setFont(font);
+ } else {
+ resultLabel->unsetFont();
+ }
+ if(use_custom_expression_font) {
+ QFont font(expressionEdit->font());
+ font.fromString(custom_expression_font);
+ expressionEdit->setFont(font);
+ } else {
+ expressionEdit->unsetFont();
+ }
+ updateStatusLabelFonts();
+ set_unicode_buttons();
+ result_display_updated();
+ if(close_to_systray != close_to_systray_was) {
+ showSystemTrayIcon(close_to_systray);
+ }
+ if(display_expression_status != display_expression_status_was) {
+ if(display_expression_status) {
+ statusLabel_l->show();
+ } else {
+ statusLabel_l->hide();
+ }
+ }
+ displayParseStatus();
+
+ bool use_button_pixmaps = false;
+ if(use_icon_buttons > 0) {
+ use_button_pixmaps = true;
+ } else if(use_icon_buttons < 0) {
+ KConfig config("kdeglobals", true, false);
+ config.setGroup("KDE");
+ use_button_pixmaps = config.readBoolEntry("ShowIconsOnPushButtons", false);
+ }
+
+ if(leftButtonsSeparator->isVisible() == use_button_pixmaps) {
+ if(use_button_pixmaps) {
+ leftButtonsLayout->setSpacing(3);
+ executeButton->setText("");
+ executeButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("exec", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
+ storeButton->setText("");
+ storeButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("filesaveas", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
+ convertButton->setText("");
+ convertButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("qalculate_convert", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
+ leftButtonsSeparator->hide();
+ stackPageButtonsLayout->setSpacing(3);
+ registerUpButton->setText("");
+ registerUpButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("up", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
+ registerDownButton->setText("");
+ registerDownButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("down", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
+ editRegisterButton->setText("");
+ editRegisterButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("edit", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
+ deleteRegisterButton->setText("");
+ deleteRegisterButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("editdelete", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
+ clearStackButton->setText("");
+ clearStackButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("view_remove", KIcon::Small, ICON_SIZE_SMALL_MEDIUM));
+ } else {
+ leftButtonsLayout->setSpacing(6);
+ if(rpn_mode) executeButton->setText(i18n("Enter"));
+ else executeButton->setText(i18n("="));
+ executeButton->setIconSet(QIconSet());
+ storeButton->setText(i18n("Store"));
+ storeButton->setIconSet(QIconSet());
+ convertButton->setText(i18n("Convert"));
+ convertButton->setIconSet(QIconSet());
+ leftButtonsSeparator->show();
+ stackPageButtonsLayout->setSpacing(6);
+ registerUpButton->setText(i18n("Up"));
+ registerUpButton->setIconSet(QIconSet());
+ registerDownButton->setText(i18n("Down"));
+ registerDownButton->setIconSet(QIconSet());
+ editRegisterButton->setText(i18n("Edit"));
+ editRegisterButton->setIconSet(QIconSet());
+ deleteRegisterButton->setText(i18n("Delete"));
+ deleteRegisterButton->setIconSet(QIconSet());
+ clearStackButton->setText(i18n("Clear"));
+ clearStackButton->setIconSet(QIconSet());
+ }
+ updateButtonWidths();
+ }
+}
+
+
+void KQalculate::copyResult() {
+ QApplication::clipboard()->setText(result_history_text, QClipboard::Clipboard);
+}
+
+void KQalculate::clearHistory() {
+ historyBrowser->setText("&nbsp;");
+ expressionEdit->setFocus();
+ inhistory.clear();
+ inhistory_type.clear();
+ inhistory_current_id = 0;
+ inhistory_id.clear();
+ initial_inhistory_index = 0;
+ initial_result_index = 0;
+}
+
+void KQalculate::convertToBestUnit() {
+ error_timer->stop();
+ mstruct->set(CALCULATOR->convertToBestUnit(*mstruct, evalops));
+ result_action_executed();
+ error_timer->start(100);
+}
+
+void KQalculate::convertToBaseUnits() {
+ error_timer->stop();
+ mstruct->set(CALCULATOR->convertToBaseUnits(*mstruct, evalops));
+ result_action_executed();
+ error_timer->start(100);
+}
+
+void KQalculate::applySetUnknowns(bool okclicked) {
+ QString str;
+ QString result_mod = "";
+ bool b = false;
+ mstruct->set(*mstruct_before_unknowns);
+ for(size_t i = 1; i <= unknowns_mstruct->size(); i++) {
+ str = unknowns_entries[i - 1]->text().stripWhiteSpace();
+ if(unknown_changed[i - 1] || !str.isEmpty()) {
+ if(!result_mod.isEmpty()) {
+ result_mod += CALCULATOR->getComma().c_str();
+ result_mod += " ";
+ }
+ result_mod += unknowns_mstruct->getChild(i)->print().c_str();
+ result_mod += "=";
+ if(str.isEmpty()) {
+ result_mod += "?";
+ } else {
+ result_mod += str;
+ mstruct->replace(*unknowns_mstruct->getChild(i), CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), evalops));
+ b = true;
+ unknown_changed[i - 1] = true;
+ }
+ }
+ }
+ if(b) {
+ b_unknowns_changed = true;
+ if(okclicked && !rpn_mode) {
+ MathStructure mp(*mstruct);
+ printops.can_display_unicode_string_arg = historyBrowser;
+ mp.format(printops);
+ str = mp.print(printops).c_str();
+ expressionEdit->blockSignals(true);
+ expressionEdit->setText(str);
+ printops.can_display_unicode_string_arg = NULL;
+ //expressionEdit->addToHistory(str);
+ expressionEdit->expression_history_index = -1;
+ expressionEdit->blockSignals(false);
+ expressionEdit->setFocus();
+ expressionEdit->selectAll();
+ expression_has_changed2 = true;
+ displayParseStatus();
+ }
+ mstruct->eval(evalops);
+ }
+ if(b_unknowns_changed) {
+ printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
+ setResult(NULL, true, false, false, result_mod);
+ }
+ //if(!okclicked && b) mstruct->set(*mstruct_before_unknowns);
+}
+void KQalculate::setUnknownsApplyClicked() {
+ applySetUnknowns(false);
+}
+void KQalculate::setUnknowns() {
+ if(expression_has_changed && !rpn_mode) execute_expression(true);
+ unknowns_mstruct = new MathStructure();
+ mstruct->findAllUnknowns(*unknowns_mstruct);
+ if(unknowns_mstruct->size() == 0) {
+ KMessageBox::error(this, i18n("No unknowns in result."));
+ return;
+ }
+ KDialogBase *dialog = new KDialogBase(this, 0, true, i18n("Set Unknowns"));
+ QObject::connect(dialog, SIGNAL(applyClicked()), this, SLOT(setUnknownsApplyClicked()));
+ QGrid *grid = dialog->makeGridMainWidget(2, Qt::Horizontal);
+ unknowns_entries.clear();
+ for(size_t i = 1; i <= unknowns_mstruct->size(); i++) {
+ new QLabel(unknowns_mstruct->getChild(i)->print().c_str(), grid);
+ unknowns_entries.push_back(new KLineEdit(grid));
+ if(i == 1) unknowns_entries[0]->setFocus();
+ }
+ mstruct_before_unknowns = new MathStructure(*mstruct);
+ b_unknowns_changed = false;
+ unknown_changed.clear();
+ unknown_changed.resize(unknowns_mstruct->size(), false);
+ int response = dialog->exec();
+ if(response == QDialog::Accepted) {
+ applySetUnknowns(true);
+ } else {
+ if(b_unknowns_changed) {
+ QString result_mod = "";
+ for(size_t i = 1; i <= unknowns_mstruct->size(); i++) {
+ if(unknown_changed[i - 1]) {
+ if(!result_mod.isEmpty()) {
+ result_mod += CALCULATOR->getComma().c_str();
+ result_mod += " ";
+ }
+ result_mod += unknowns_mstruct->getChild(i)->print().c_str();
+ result_mod += "=";
+ result_mod += "?";
+ }
+ }
+ mstruct->set(*mstruct_before_unknowns);
+ printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
+ setResult(NULL, true, false, false, result_mod);
+ expressionEdit->setFocus();
+ }
+ }
+ delete dialog;
+ delete mstruct_before_unknowns;
+ delete unknowns_mstruct;
+}
+
+
+void KQalculate::manageDataSets() {
+ if(!datasets_dialog) {
+ datasets_dialog = new QalculateDataSetsDialog();
+ datasets_dialog->updateDataSetTree();
+ QObject::connect(datasets_dialog, SIGNAL(dataSetsChanged()), this, SLOT(update_fmenu()));
+ }
+ datasets_dialog->show();
+}
+
+void KQalculate::factorize() {
+ executeCommand(COMMAND_FACTORIZE);
+}
+void KQalculate::simplify() {
+ executeCommand(COMMAND_SIMPLIFY);
+}
+
+void KQalculate::manageUnits() {
+ if(!units_dialog) {
+ units_dialog = new QalculateUnitsDialog();
+ units_dialog->updateUnitTree();
+ QObject::connect(units_dialog, SIGNAL(unitsChanged()), this, SLOT(update_umenus()));
+ QObject::connect(units_dialog, SIGNAL(insertRequest(Unit*)), this, SLOT(insertUnit(Unit*)));
+ QObject::connect(units_dialog, SIGNAL(convertRequest(Unit*)), this, SLOT(convertResult(Unit*)));
+ }
+ units_dialog->show();
+}
+void KQalculate::insertUnit(Unit *u) {
+ if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) {
+ insert_text(((CompositeUnit*) u)->print(true, printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) expressionEdit).c_str());
+ } else {
+ insert_text(u->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, true, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str());
+ }
+ unit_inserted(u);
+}
+void KQalculate::convertResult(Unit *u) {
+ error_timer->stop();
+ mstruct->set(CALCULATOR->convert(*mstruct, u, evalops));
+ result_action_executed();
+ error_timer->start(100);
+}
+void KQalculate::insertMatrixVector(const MathStructure *m, bool do_vector, bool is_text_struct, bool is_result) {
+ if(!insert_matrix_dialog) {
+ insert_matrix_dialog = new QalculateInsertMatrixVectorDialog(this);
+ }
+ QString str = insert_matrix_dialog->editMatrixVector(m, do_vector, is_text_struct, is_result);
+ if(!str.isEmpty()) {
+ insert_text(str);
+ }
+}
+void KQalculate::insertMatrix() {
+ QString str = expressionEdit->selectedText().stripWhiteSpace();
+ if(!str.isEmpty()) {
+ MathStructure mstruct_sel;
+ CALCULATOR->beginTemporaryStopMessages();
+ CALCULATOR->parse(&mstruct_sel, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), evalops.parse_options);
+ CALCULATOR->endTemporaryStopMessages();
+ if(mstruct_sel.isMatrix()) {
+ insertMatrixVector(&mstruct_sel, false);
+ return;
+ }
+ }
+ insertMatrixVector(NULL, false);
+}
+void KQalculate::insertVector() {
+ QString str = expressionEdit->selectedText().stripWhiteSpace();
+ if(!str.isEmpty()) {
+ MathStructure mstruct_sel;
+ CALCULATOR->beginTemporaryStopMessages();
+ CALCULATOR->parse(&mstruct_sel, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), evalops.parse_options);
+ CALCULATOR->endTemporaryStopMessages();
+ if(mstruct_sel.isVector() && !mstruct_sel.isMatrix()) {
+ insertMatrixVector(&mstruct_sel, true);
+ return;
+ }
+ }
+ insertMatrixVector(NULL, true);
+}
+
+void KQalculate::keyPressEvent(QKeyEvent *e) {
+ KMainWindow::keyPressEvent(e);
+ if(e->isAccepted()) return;
+ if(close_to_systray && e->key() == Key_Escape && e->state() == 0) {
+ e->accept();
+ hide();
+ return;
+ }
+ if(!expressionEdit->hasFocus() && e->key() != Qt::Key_Control && e->key() != Qt::Key_Meta && e->key() != Qt::Key_Shift && e->key() != Qt::Key_Alt) {
+ expressionEdit->setFocus();
+ expressionEdit->keyPressEvent(e);
+ }
+}
+
+bool KQalculate::queryClose() {
+ if(m_parent->sessionSaving() || !close_to_systray) return true;
+ hide();
+ setShown(false);
+ return false;
+}
+void KQalculate::saveProperties(KConfig*) {
+ KConfig *cfg = KGlobal::config();
+ cfg->setGroup("Session");
+ cfg->writeEntry("docked", isHidden());
+}
+void KQalculate::readProperties(KConfig*) {
+ KConfig *cfg = KGlobal::config();
+ cfg->setGroup("Session");
+ if(close_to_systray && cfg->readBoolEntry("docked", true)) {
+ hide();
+ } else {
+ show();
+ }
+}
+
+void KQalculate::display_function_hint(MathFunction *f, int arg_index) {
+ if(!f) return;
+ int iargs = f->maxargs();
+ Argument *arg;
+ Argument default_arg;
+ QString str, str2, str3;
+ const ExpressionName *ename = &f->preferredName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) statusLabel_l);
+ bool last_is_vctr = f->getArgumentDefinition(iargs) && f->getArgumentDefinition(iargs)->type() == ARGUMENT_TYPE_VECTOR;
+ if(arg_index > iargs && iargs >= 0 && !last_is_vctr) {
+ statusLabel_l->setText(i18n("Too many arguments for %1().").arg(ename->name.c_str()), false, false, true);
+ return;
+ }
+ str += ename->name.c_str();
+ if(iargs < 0) {
+ iargs = f->minargs() + 1;
+ if(arg_index > iargs) arg_index = iargs;
+ }
+ if(arg_index > iargs && last_is_vctr) arg_index = iargs;
+
+ str += "(";
+ int i_reduced = 0;
+ if(iargs != 0) {
+ for(int i2 = 1; i2 <= iargs; i2++) {
+ if(i2 > f->minargs() && arg_index < i2) {
+ str += "[";
+ }
+ if(i2 > 1) {
+ str += CALCULATOR->getComma().c_str();
+ str += " ";
+ }
+ if(i2 == arg_index) str += "<b>";
+ arg = f->getArgumentDefinition(i2);
+ if(arg && !arg->name().empty()) {
+ str2 = arg->name().c_str();
+ } else {
+ str2 = i18n("argument");
+ str2 += " ";
+ str2 += QString::number(i2);
+ }
+ if(i2 == arg_index) {
+ if(arg) {
+ if(i_reduced == 2) str3 = arg->print().c_str();
+ else str3 = arg->printlong().c_str();
+ } else {
+ Argument arg_default;
+ if(i_reduced == 2) str3 = arg_default.print().c_str();
+ else str3 = arg_default.printlong().c_str();
+ }
+ if(!str3.isEmpty()) {
+ str2 += ": ";
+ str2 += str3;
+ }
+ str2.replace("&", "&amp;");
+ str2.replace(">", "&gt;");
+ str2.replace("<", "&lt;");
+ str += str2;
+ str += "</b>";
+ if(i_reduced < 2) {
+ QSimpleRichText qsrt(str, statusLabel_l->font());
+ qsrt.setWidth(statusLabel_l->contentsRect().width() + 100);
+ if(qsrt.widthUsed() > statusLabel_l->contentsRect().width() - 4) {
+ str = ename->name.c_str();
+ str += "(";
+ if(i2 != 1) {
+ str += "...";
+ i_reduced++;
+ } else {
+ i_reduced = 2;
+ }
+ i2--;
+ }
+ } else {
+ i_reduced = 0;
+ }
+ } else {
+ str2.replace("&", "&amp;");
+ str2.replace(">", "&gt;");
+ str2.replace("<", "&lt;");
+ str += str2;
+ if(i2 > f->minargs() && arg_index < i2) {
+ str += "]";
+ }
+ }
+ }
+ if(f->maxargs() < 0) {
+ str += CALCULATOR->getComma().c_str();
+ str += " ...";
+ }
+ }
+ str += ")";
+ statusLabel_l->setText(str, false, false, false);
+}
+
+void KQalculate::displayParseStatus() {
+ if(!display_expression_status) return;
+ if(expressionEdit->text().length() == 0) {
+ statusLabel_l->setText("", true, false, false);
+ parsed_expression = "";
+ expression_has_changed2 = false;
+ had_errors_before = false;
+ had_warnings_before = false;
+ return;
+ }
+ MathStructure mparse, mfunc;
+ string str_e, str_u;
+ int pos = expressionEdit->cursorPosition();
+ bool full_parsed = false;
+ bool had_errors = false, had_warnings = false;
+ evalops.parse_options.preserve_format = true;
+ if(pos > 0) {
+ evalops.parse_options.unended_function = &mfunc;
+ CALCULATOR->beginTemporaryStopMessages();
+ if(pos < (int) expressionEdit->text().length()) {
+ QString str = expressionEdit->text();
+ str.truncate(pos);
+ str_e = CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options);
+ if(!CALCULATOR->separateToExpression(str_e, str_u, evalops)) {
+ CALCULATOR->parse(&mparse, str_e, evalops.parse_options);
+ }
+ } else {
+ str_e = CALCULATOR->unlocalizeExpression(expressionEdit->text().ascii(), evalops.parse_options);
+ CALCULATOR->separateToExpression(str_e, str_u, evalops);
+ CALCULATOR->parse(&mparse, str_e, evalops.parse_options);
+ full_parsed = true;
+ }
+ int warnings_count;
+ had_errors = CALCULATOR->endTemporaryStopMessages(NULL, &warnings_count) > 0;
+ had_warnings = warnings_count > 0;
+ evalops.parse_options.unended_function = NULL;
+ }
+ if(mfunc.isFunction()) {
+ if(mfunc.countChildren() == 0) {
+ display_function_hint(mfunc.function(), 1);
+ } else {
+ display_function_hint(mfunc.function(), mfunc.countChildren());
+ }
+ }
+ if(expression_has_changed2) {
+ if(!full_parsed) {
+ CALCULATOR->beginTemporaryStopMessages();
+ str_e = CALCULATOR->unlocalizeExpression(expressionEdit->text().ascii(), evalops.parse_options);
+ CALCULATOR->separateToExpression(str_e, str_u, evalops);
+ CALCULATOR->parse(&mparse, str_e, evalops.parse_options);
+ int warnings_count;
+ had_errors = CALCULATOR->endTemporaryStopMessages(NULL, &warnings_count) > 0;
+ had_warnings = warnings_count > 0;
+ }
+ PrintOptions po;
+ po.preserve_format = true;
+ po.show_ending_zeroes = true;
+ po.lower_case_e = printops.lower_case_e;
+ po.lower_case_numbers = printops.lower_case_numbers;
+ po.base_display = printops.base_display;
+ po.abbreviate_names = false;
+ po.hide_underscore_spaces = true;
+ po.use_unicode_signs = printops.use_unicode_signs;
+ po.multiplication_sign = printops.multiplication_sign;
+ po.division_sign = printops.division_sign;
+ po.short_multiplication = false;
+ po.excessive_parenthesis = true;
+ po.improve_division_multipliers = false;
+ po.can_display_unicode_string_function = &can_display_unicode_string_function;
+ po.can_display_unicode_string_arg = (void*) statusLabel_l;
+ po.spell_out_logical_operators = printops.spell_out_logical_operators;
+ po.restrict_to_parent_precision = false;
+ mparse.format(po);
+ parsed_expression = mparse.print(po).c_str();
+ if(!str_u.empty()) {
+ parsed_expression += CALCULATOR->localToString().c_str();
+ CALCULATOR->beginTemporaryStopMessages();
+ CompositeUnit cu("", "temporary_composite_parse", "", str_u);
+ int warnings_count;
+ had_errors = CALCULATOR->endTemporaryStopMessages(NULL, &warnings_count) > 0 || had_errors;
+ had_warnings = had_warnings || warnings_count > 0;
+ mparse = cu.generateMathStructure(!printops.negative_exponents);
+ mparse.format(po);
+ parsed_expression += mparse.print(po).c_str();
+ }
+ parsed_expression.replace("&", "&amp;");
+ parsed_expression.replace(">", "&gt;");
+ parsed_expression.replace("<", "&lt;");
+ if(!mfunc.isFunction()) statusLabel_l->setText(parsed_expression, true, had_errors, had_warnings);
+ expression_has_changed2 = false;
+ had_errors_before = had_errors;
+ had_warnings_before = had_warnings;
+ } else if(!mfunc.isFunction()) {
+ statusLabel_l->setText(parsed_expression, true, had_errors_before, had_warnings_before);
+ }
+ evalops.parse_options.preserve_format = false;
+}
+
+void KQalculate::editHistoryExpression() {
+ if(current_history_index < inhistory.size()) {
+ QString text = inhistory[current_history_index];
+ text.replace("&amp;", "&");
+ text.replace("&gt;", ">");
+ text.replace("&lt;", "<");
+ text.replace("<br>", " ");
+ expressionEdit->setText(text);
+ expressionEdit->setFocus();
+ }
+}
+void KQalculate::editHistoryParse() {
+ if(current_history_index < inhistory.size()) {
+ QString text = inhistory[current_history_index];
+ text.replace("&amp;", "&");
+ text.replace("&gt;", ">");
+ text.replace("&lt;", "<");
+ text.replace("<br>", " ");
+ expressionEdit->setText(text);
+ expressionEdit->setFocus();
+ }
+}
+void KQalculate::editHistoryResult() {
+ if(current_history_index < inhistory.size()) {
+ QString text = inhistory[current_history_index];
+ text.replace("&amp;", "&");
+ text.replace("&gt;", ">");
+ text.replace("&lt;", "<");
+ text.replace("<br>", " ");
+ expressionEdit->setText(text);
+ expressionEdit->setFocus();
+ }
+}
+void KQalculate::insertHistoryResultVariable() {
+ if(current_history_index < inhistory.size()) {
+ int id = inhistory_id[current_history_index];
+ for(size_t i = 0; i < 5; i++) {
+ if(vans_id_start[i] != -1 && id >= vans_id_start[i] && (vans_id_end[i] == -1 || id <= vans_id_end[i])) {
+ insertVariable(vans[i]);
+ }
+ }
+ }
+}
+
+QalculateHistoryBrowser::QalculateHistoryBrowser(QWidget *parent, const char *name) : KTextBrowser(parent, name) {}
+QalculateHistoryBrowser::~QalculateHistoryBrowser() {}
+
+QPopupMenu *QalculateHistoryBrowser::createPopupMenu(const QPoint &pos) {
+
+ QPopupMenu *menu = KTextBrowser::createPopupMenu(pos);
+ menu->insertSeparator();
+ mainWin->ActionClearHistory->plug(menu);
+ QString name = anchorAt(pos, Qt::AnchorName);
+ if(!name.isEmpty()) {
+ int id = name.toInt();
+ QValueVector<int>::size_type i = 0;
+ for(; i < inhistory_id.size(); i++) {
+ if(inhistory_id[i] == id) {
+ break;
+ }
+ }
+ mainWin->current_history_index = i;
+ if(i < inhistory_id.size()) {
+ switch(inhistory_type[i]) {
+ case QALCULATE_HISTORY_PARSE: {}
+ case QALCULATE_HISTORY_PARSE_APPROXIMATE: {
+ menu->insertItem(i18n("Edit Expression"), mainWin, SLOT(editHistoryParse()));
+ break;
+ }
+ case QALCULATE_HISTORY_EXPRESSION: {
+ menu->insertItem(i18n("Edit Expression"), mainWin, SLOT(editHistoryExpression()));
+ break;
+ }
+ case QALCULATE_HISTORY_RESULT_APPROXIMATE: {}
+ case QALCULATE_HISTORY_RESULT: {
+ menu->insertItem(i18n("Edit Result"), mainWin, SLOT(editHistoryResult()));
+ for(size_t i = 0; i < 5; i++) {
+ if(vans_id_start[i] != -1 && id >= vans_id_start[i] && (vans_id_end[i] == -1 || id <= vans_id_end[i])) {
+ menu->insertItem(i18n("Insert Result Variable"), mainWin, SLOT(insertHistoryResultVariable()));
+ break;
+ }
+ }
+ break;
+ }
+ default: {}
+ }
+ }
+ }
+ return menu;
+
+}
+
+
+QalculateParseLabel::QalculateParseLabel(QWidget *parent, const char *name) : QLabel(parent, name) {
+ QLabel::setText("<b>A</b>");
+ bb = false;
+ ec = false;
+ wc = false;
+}
+QalculateParseLabel::~QalculateParseLabel() {}
+void QalculateParseLabel::setText(QString text, bool break_begin, bool error_color, bool warning_color) {
+ bb = break_begin;
+ ec = error_color;
+ wc = warning_color;
+ parsetext = "<nobr>";
+ parsetext += text;
+ parsetext += "</nobr>";
+ update();
+}
+void QalculateParseLabel::drawContents(QPainter *p) {
+ QColorGroup cg = colorGroup();
+ if(ec) {
+ cg.setColor(QColorGroup::Text, status_error_color);
+ } else if(wc) {
+ cg.setColor(QColorGroup::Text, status_warning_color);
+ } else if(backgroundMode() != PaletteBase && isEnabled()) {
+ cg.setColor(QColorGroup::Text, paletteForegroundColor());
+ }
+
+ QRect cr = contentsRect();
+ cr.setX(cr.x() + 4);
+ cr.setWidth(cr.width() - 4);
+ QSimpleRichText qsrt(parsetext, font());
+ qsrt.setWidth(p, cr.width() + 100);
+ if(qsrt.widthUsed() > cr.width()) {
+ if(bb) {
+ QSimpleRichText qsrt_dots("...", font());
+ qsrt_dots.draw(p, cr.x(), cr.y(), cr, cg, 0);
+ cr.setX(cr.x() + qsrt_dots.widthUsed());
+ cr.setWidth(cr.width() - qsrt_dots.widthUsed());
+ qsrt.draw(p, cr.x() + cr.width() - qsrt.widthUsed(), cr.y(), cr, cg, 0);
+ } else {
+ QSimpleRichText qsrt_dots("...", font());
+ qsrt_dots.draw(p, cr.x() + cr.width() - qsrt_dots.widthUsed(), cr.y(), cr, cg, 0);
+ cr.setWidth(cr.width() - qsrt_dots.widthUsed());
+ qsrt.draw(p, cr.x(), cr.y(), cr, cg, 0);
+ }
+ } else {
+ qsrt.draw(p, cr.x(), cr.y(), cr, cg, 0);
+ }
+}
+
+QalculateButton::QalculateButton(QWidget *parent, const char *name) : QPushButton(parent, name) {
+ setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
+ umtcw = true;
+#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4
+ KAcceleratorManager::setNoAccel(this);
+#endif
+
+}
+QalculateButton::QalculateButton(const QString &text, QWidget *parent, const char *name) : QPushButton(text, parent, name) {
+ setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
+ umtcw = true;
+#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4
+ KAcceleratorManager::setNoAccel(this);
+#endif
+}
+QalculateButton::QalculateButton(const QIconSet &icon, const QString &text, QWidget *parent, const char *name) : QPushButton(icon, text, parent, name) {
+ setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
+ umtcw = true;
+#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4
+ KAcceleratorManager::setNoAccel(this);
+#endif
+}
+QalculateButton::~QalculateButton() {}
+
+void QalculateButton::setUseMinThreeCharWidth(bool b) {
+ umtcw = b;
+}
+void QalculateButton::setMarkup(const QString &str) {
+ QColorGroup cg(colorGroup());
+ cg.setColor(QColorGroup::Text, paletteForegroundColor());
+ QSimpleRichText rtext(str, font());
+ QPicture picture;
+ QPainter p(&picture);
+ rtext.draw(&p, 0, 0, QRect(), cg);
+ p.flush();
+ p.end();
+ QRect r = picture.boundingRect();
+ QPixmap pixmap(r.width(), rtext.height());
+ pixmap.fill(cg.background());
+ QPainter p2(&pixmap);
+ p2.drawPicture(-r.x(), 0, picture);
+ p2.flush();
+ p2.end();
+ pixmap.setMask(pixmap.createHeuristicMask());
+ setPixmap(pixmap);
+}
+
+QSize QalculateButton::sizeHint() const {
+
+ constPolish();
+
+ int w = 0, h = 0;
+
+
+#ifndef QT_NO_ICONSET
+ if(iconSet() && !iconSet()->isNull()) {
+ w = iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 10;
+ h = iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height() + 10;
+ return QSize(w, h).expandedTo(QApplication::globalStrut());
+ }
+#endif
+
+ QSize sz;
+
+ if(pixmap()) {
+ QPixmap *pm = (QPixmap *)pixmap();
+ w = pm->width();
+ h = pm->height();
+ if(umtcw) {
+ QFontMetrics fm = fontMetrics();
+ sz = fm.size(ShowPrefix, QString::fromLatin1("XXX"));
+ if(w < sz.width()) w = sz.width();
+ if(w < sz.height()) w = sz.height();
+ }
+ sz.setWidth(w);
+ sz.setHeight(h);
+ w += 12;
+ h += 10;
+ } else {
+ QFontMetrics fm = fontMetrics();
+ if(umtcw && (text().isEmpty() || text().length() < 3)) {
+ sz = fm.size(ShowPrefix, QString::fromLatin1("XXX"));
+ } else {
+ sz = fm.size(ShowPrefix, text());
+ }
+ w = sz.width() + 12;
+ h = sz.height() + 10;
+ }
+
+ return QSize(w, h).boundedTo(style().sizeFromContents(QStyle::CT_PushButton, this, sz)).expandedTo(QApplication::globalStrut());
+
+}
+
+QalculateStyleSheet::QalculateStyleSheet(QObject *parent, const char *name) : QStyleSheet(parent, name) {}
+QalculateStyleSheet::~QalculateStyleSheet() {}
+
+void QalculateStyleSheet::scaleFont(QFont &font, int logicalSize) const {
+
+ if(logicalSize <= 1) {
+ font.setPixelSize(1);
+ } else if(logicalSize == 2) {
+ logicalSize = 1;
+ } else if(logicalSize > 7) {
+ logicalSize = 7;
+ }
+
+ int baseSize = font.pointSize();
+
+ bool pixel = FALSE;
+ if(baseSize == -1){
+ baseSize = font.pixelSize();
+ pixel = TRUE;
+ }
+
+ float factor = baseSize;
+ int i;
+ int scale_level = logicalSize - 3;
+
+ if(scale_level > 0) {
+ i = 0;
+ while (i < scale_level) {
+ factor *= 1.2;
+ ++i;
+ }
+ } else if(scale_level < 0) {
+ i = scale_level;
+ while (i < 0) {
+ factor /= 1.2;
+ ++i;
+ }
+ }
+
+ if(pixel) font.setPixelSize((int) roundf(factor));
+ else font.setPointSizeFloat(factor);
+
+}
+
+QalculateRPNStackListView::QalculateRPNStackListView(QWidget *parent, const char *name) : KListView(parent, name) {}
+QalculateRPNStackListView::~QalculateRPNStackListView() {}
+
+void QalculateRPNStackListView::keyPressEvent(QKeyEvent *e) {
+ switch(e->key()) {
+ case Key_Prior: {}
+ case Key_Next: {}
+ case Key_Home: {}
+ case Key_End: {}
+ case Key_Up: {}
+ case Key_Down: {
+ KListView::keyPressEvent(e);
+ break;
+ }
+ default: {
+ if(e->key() == KGlobalSettings::contextMenuKey()) KListView::keyPressEvent(e);
+ else e->ignore();
+ }
+ }
+}
+
+#include "kqalculate.moc"
diff --git a/src/kqalculate.h b/src/kqalculate.h
new file mode 100644
index 0000000..fb016e0
--- /dev/null
+++ b/src/kqalculate.h
@@ -0,0 +1,593 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef KQALCULATE_H
+#define KQALCULATE_H
+
+#include <qvariant.h>
+#include <kmainwindow.h>
+#include <qvaluevector.h>
+#include <qlabel.h>
+#include <qpushbutton.h>
+#include <qstylesheet.h>
+#include <ktextbrowser.h>
+#include <klistview.h>
+#include <kdialogbase.h>
+#include <kshortcut.h>
+
+class Prefix;
+class QalculatePrecisionDialog;
+class Variable;
+class MathFunction;
+class Unit;
+class QalculateDecimalsDialog;
+class QalculateEditVariableDialog;
+class QalculateEditMatrixVectorDialog;
+class QalculateEditUnitDialog;
+class QalculateEditFunctionDialog;
+class QalculateEditDataSetDialog;
+class QalculateEditUnknownVariableDialog;
+class QalculateVariablesDialog;
+class QalculateFunctionsDialog;
+class QalculateUnitsDialog;
+class QalculateDataSetsDialog;
+class QalculateConvertUnitsDialog;
+class KAction;
+class KRadioAction;
+class KToggleAction;
+class QToolBar;
+class QPopupMenu;
+class KPushButton;
+class QalculateExpressionEdit;
+class QalculateResultDisplay;
+class QFrame;
+class QWidgetStack;
+class QWidget;
+class QComboBox;
+class QalculateHistoryBrowser;
+class QalculateConvertNumberBasesDialog;
+class QalculatePeriodicTableDialog;
+class QalculatePlotDialog;
+class QalculateSetBaseDialog;
+class KLineEdit;
+class MathStructure;
+class QalculateImportCSVDialog;
+class QalculateExportCSVDialog;
+class QalculatePreferencesDialog;
+class QalculateInsertMatrixVectorDialog;
+class KSystemTray;
+class QalculateParseLabel;
+class QButtonGroup;
+class QRadioButton;
+class QalculateButton;
+class QVBoxLayout;
+class KSeparator;
+class KUniqueApplication;
+class KConfig;
+class QListViewItem;
+class QalculateRPNStackListView;
+class KGlobalAccel;
+class KKeyButton;
+
+void *view_proc(void *pipe);
+void *command_proc(void *pipe);
+
+enum {
+ COMMAND_FACTORIZE,
+ COMMAND_SIMPLIFY
+};
+
+
+class ModeObject : public QObject {
+
+ Q_OBJECT
+
+ public:
+
+ ModeObject(int mode);
+ int i_mode;
+
+ public slots:
+
+ void loadMode();
+
+};
+
+class KQalculate : public KMainWindow {
+
+ Q_OBJECT
+
+public:
+
+ KQalculate(KUniqueApplication *parent = 0, const char* name = 0, WFlags fl = WType_TopLevel | WDestructiveClose);
+ virtual ~KQalculate();
+
+ void setupActions();
+ void setAssumptionsMenu();
+ void setModeActions();
+ void execute_expression(bool force = true);
+ void setResult(Prefix *prefix = NULL, bool update_history = true, bool update_parse = false, bool force = false, QString transformation = "", size_t stack_index = 0, bool register_moved = false);
+ void executeCommand(int command_type);
+ void result_display_updated();
+ void result_format_updated();
+ void result_action_executed();
+ void result_prefix_changed(Prefix *prefix = NULL);
+ void expression_calculation_updated();
+ void expression_format_updated(bool recalculate = false);
+ void display_errors(QString *new_text = NULL, int *inhistory_index = NULL);
+ void update_status_text();
+ void display_function_hint(MathFunction *f, int arg_index = 1);
+ void clearresult();
+ void create_fmenu();
+ void create_vmenu();
+ void create_umenu();
+ void create_toumenu();
+ void create_setpmenu();
+ void recreate_recent_functions();
+ void recreate_recent_variables();
+ void recreate_recent_units();
+ void function_inserted(MathFunction *object);
+ void variable_inserted(Variable *object);
+ void unit_inserted(Unit *object);
+ void updateStatusLabelFonts();
+ void set_unicode_buttons();
+ void insertButtonFunction(QString text, bool append_space = true);
+ void insertButtonFunction(MathFunction *f);
+ const MathStructure *getResultPart(int);
+ void insertMatrixVector(const MathStructure *m = NULL, bool do_vector = false, bool is_text_struct = false, bool is_result = false);
+
+ void calculateRPN(int op);
+ void calculateRPN(MathFunction *f);
+ void RPNStackEnter(Variable *v);
+ void RPNRegisterAdded(const QString &text, size_t index = 0);
+ void RPNRegisterRemoved(size_t index);
+ void RPNRegisterChanged(const QString &text, size_t index = 0);
+
+ QalculateInsertMatrixVectorDialog *insert_matrix_dialog;
+ QalculatePrecisionDialog *precisionDialog;
+ QalculateDecimalsDialog *decimalsDialog;
+ QalculateConvertUnitsDialog *convert_to_unit_expression_dialog;
+ QalculateEditVariableDialog *variable_edit_dialog, *store_dialog;
+ QalculateEditMatrixVectorDialog *matrix_edit_dialog;
+ QalculateEditUnitDialog *unit_edit_dialog;
+ QalculateEditFunctionDialog *function_edit_dialog;
+ QalculateEditDataSetDialog *dataset_edit_dialog;
+ QalculateEditUnknownVariableDialog *unknown_edit_dialog;
+ QalculateVariablesDialog *variables_dialog;
+ QalculateFunctionsDialog *functions_dialog;
+ QalculateUnitsDialog *units_dialog;
+ QalculateDataSetsDialog *datasets_dialog;
+ QalculateConvertNumberBasesDialog *convert_number_bases_dialog;
+ QalculatePeriodicTableDialog *periodic_table_dialog;
+ QalculateImportCSVDialog *import_csv_dialog;
+ QalculateExportCSVDialog *export_csv_dialog;
+ QalculatePlotDialog *plot_dialog;
+ QalculateSetBaseDialog *set_base_dialog;
+ QalculatePreferencesDialog *preferences_dialog;
+ QMap <int, Variable*> menu_variables_ids;
+ QMap <int, MathFunction*> menu_functions_ids;
+ QMap <int, Unit*> menu_units_ids, menu_to_unit_ids;
+ QMap <int, Prefix*> menu_units_prefixes_ids, menu_set_prefix_ids;
+ QValueVector<int> recent_function_ids;
+ QValueVector<int> recent_variable_ids;
+ QValueVector<int> recent_unit_ids;
+
+ QalculateRPNStackListView *stackList;
+ QVBoxLayout *stackPageButtonsLayout;
+ QalculateButton *registerUpButton, *registerDownButton, *deleteRegisterButton, *editRegisterButton, *clearStackButton;
+ QPopupMenu *stackMenu;
+ KUniqueApplication *m_parent;
+ KSystemTray *trayicon;
+ QalculateButton *executeButton, *storeButton, *convertButton;
+ QalculateButton *functionsButton;
+ QVBoxLayout *leftButtonsLayout;
+ KSeparator *leftButtonsSeparator;
+ QalculateExpressionEdit* expressionEdit;
+ QLabel *statusLabel_r;
+ QalculateParseLabel *statusLabel_l;
+ QalculateResultDisplay* resultLabel;
+ QWidgetStack* mainStack;
+ QFrame *bottomLine;
+ QWidget *keypadPage, *historyPage, *stackPage;
+ QComboBox* kpNumericCombo, *kpBaseCombo;
+ QRadioButton *kpDegreesButton, *kpRadiansButton, *kpGradiansButton, *kpNoAngleUnitButton;
+ QButtonGroup *kpAngleGroup;
+ QPushButton *kpExact, *kpFraction;
+ QalculateButton *kpSquare, *kpLog, *kpHyp, *kpSqrt, *kpCos, *kpRaise, *kpInv, *kpSin;
+ QalculateButton *kpTan, *kpLn, *kpFactorial, *kpMod, *kpAns, *kp8, *kp0, *kp7, *kpDel, *kpDot, *kp5, *kpEquals, *kpClear;
+ QalculateButton *kp3, *kp1, *kp4, *kp9, *kpDivision, *kpExp, *kp6, *kp2, *kpMinus, *kpTimes, *kpPlus;
+ QalculateHistoryBrowser *historyBrowser;
+ QPushButton *historyButton, *keypadButton, *stackButton;
+ KMenuBar *menubar;
+ QPopupMenu *menu_functions, *menu_variables, *menu_units, *menu_to_unit, *menu_set_prefix, *menu_modes;
+ KToggleAction *ActionAbbreviateNames, *ActionReadPrecision, *ActionNonZeroDenominators, *ActionWarnAboutDenominatorsAssumedNonZero;
+ KToggleAction *ActionLimitImplicitMultiplication, *ActionRPNMode, *ActionRPNSyntax, *ActionIndicateInfiniteSeries, *ActionNegativeExponents, *ActionSortMinusLast;
+ KToggleAction *ActionShowEndingZeroes, *ActionRoundHalfwayNumbersToEven, *ActionEnablePrefixes;
+ KToggleAction *ActionEnableUseOfAllPrefixes, *ActionEnableDenominatorPrefixes, *ActionPlaceUnitsSeparately;
+ KToggleAction *ActionEnableVariables, *ActionEnableFunctions, *ActionEnableUnits, *ActionEnableUnknowns;
+ KToggleAction *ActionCalculateVariables, *ActionAllowComplexResult, *ActionAllowInfiniteResult;
+ KRadioAction *ActionApproximationAlwaysExact, *ActionApproximationTryExact, *ActionApproximationApproximate;
+ KRadioAction *ActionAlgebraicModeSimplify, *ActionAlgebraicModeFactorize, *ActionAlgebraicModeNone;
+ KRadioAction *ActionFractionalDisplayDecimal, *ActionFractionalDisplayDecimalTryExact;
+ KRadioAction *ActionFractionalDisplayFraction, *ActionFractionalDisplayCombined;
+ KRadioAction *ActionNumericalDisplayEngineering, *ActionNumericalDisplayScientific, *ActionNumericalDisplayPurelyScientific, *ActionNumericalDisplaySimple, *ActionNumericalDisplayNormal;
+ KRadioAction *ActionNumberBaseBinary, *ActionNumberBaseOctal, *ActionNumberBaseDecimal, *ActionNumberBaseHexadecimal, *ActionNumberBaseOther;
+ KRadioAction *ActionNumberBaseSexagesimal, *ActionNumberBaseTimeFormat, *ActionNumberBaseRomanNumerals;
+ KRadioAction *ActionAssumptionTypeUnknown, *ActionAssumptionTypeNonMatrix, *ActionAssumptionTypeNumber, *ActionAssumptionTypeComplex, *ActionAssumptionTypeReal;
+ KRadioAction *ActionAssumptionTypeRational, *ActionAssumptionTypeInteger, *ActionAssumptionSignUnknown, *ActionAssumptionSignNonZero;
+ KRadioAction *ActionAssumptionSignPositive, *ActionAssumptionSignNonNegative, *ActionAssumptionSignNegative;
+ KRadioAction *ActionAssumptionSignNonPositive, *ActionAngleUnitDegrees, *ActionAngleUnitRadians, *ActionAngleUnitGradians;
+ KRadioAction *ActionAngleUnitNone, *ActionAutoNoConversion, *ActionAutoConvertToBaseUnits, *ActionAutoConvertToBestUnit;
+ KAction *ActionSetBase, *ActionPrecision, *ActionDecimals, *ActionSaveModeAs, *ActionDeleteMode, *ActionSaveMode, *ActionQuit;
+ KAction *ActionUpdateExchangeRates, *ActionManageVariables, *ActionConvertToUnitExpression, *ActionStoreResult, *ActionClose;
+ KAction *ActionConvertNumberBases, *ActionManageFunctions, *ActionConvertToBaseUnits, *ActionConvertToBestUnit;
+ KAction *ActionManageUnits, *ActionManageDataSets, *ActionFactorize, *ActionSimplify, *ActionSetUnknowns, *ActionCopyResult;
+ KAction *ActionPreferences, *ActionSaveAsImage, *ActionImportCSVFile, *ActionExportCSVFile, *ActionPeriodicTable;
+ KAction *ActionPlotFunctionsData, *ActionSaveDefinitions, *ActionNewVariable, *ActionNewMatrix, *ActionNewVector;
+ KAction *ActionNewUnknownVariable, *ActionNewFunction, *ActionNewUnit, *ActionNewDataSet;
+ KAction *ActionInsertMatrix, *ActionInsertVector;
+ KAction *ActionClearHistory;
+ KAction *ActionHideSystemTrayIcon, *ActionHide;
+ KAction *ActionClearStack, *ActionDeleteRegister, *ActionEditRegister;
+ KAction *ActionConfigureGlobalShortcuts;
+
+ KGlobalAccel *globalAccel;
+
+ QValueVector<int>::size_type current_history_index;
+ QValueVector<ModeObject*> mode_objects;
+
+public slots:
+
+ void executeCommand2();
+ void setResult2();
+ void execute_expression2();
+
+ void showHide();
+ void configureGlobalShortcuts();
+
+ void update_fmenu();
+ void update_vmenu();
+ void update_umenus();
+ void insertVariable(Variable*);
+ void insertFunction(MathFunction*, QWidget *parent);
+ void applyFunction(MathFunction*, QWidget *parent);
+ void onExpressionChanged();
+ void onErrorTimeout();
+ bool fetch_exchange_rates(int);
+ void update_completion();
+ void insert_text(QString);
+ void aboutToQuit();
+ void onVariableMenuItemActivated(int);
+ void onFunctionMenuItemActivated(int);
+ void onUnitMenuItemActivated(int);
+ void onUnitsPrefixMenuItemActivated(int);
+ void precisionRecalculate();
+ void setMaxDecimals(int);
+ void setMinDecimals(int);
+ void execute();
+ void toggleHistory(bool);
+ void toggleStack(bool);
+ void toggleKeypad(bool);
+ void showEndingZeroes(bool);
+ void approximationTryExact();
+ void approximationAlwaysExact();
+ void approximationApproximate();
+ void fractionalDisplayDecimal();
+ void fractionalDisplayDecimalTryExact();
+ void fractionalDisplayFraction();
+ void fractionalDisplayCombined();
+ void numericalDisplayNormal();
+ void numericalDisplayEngineering();
+ void numericalDisplayScientific();
+ void numericalDisplayPurelyScientific();
+ void numericalDisplaySimple();
+ void indicateInfiniteSeries(bool);
+ void sortMinusLast(bool);
+ void negativeExponents(bool);
+ void roundHalfwayNumbersToEven(bool);
+ void abbreviateNames(bool);
+ void updateBaseOther();
+ void numberBaseBinary();
+ void numberBaseOctal();
+ void numberBaseDecimal();
+ void numberBaseOther();
+ void numberBaseHexadecimal();
+ void numberBaseSexagesimal();
+ void numberBaseTimeFormat();
+ void numberBaseRomanNumerals();
+ void setBaseInResultFromDialogGroup(int);
+ void setBaseInResultFromDialogBox(int);
+ void setBaseInExpressionFromDialogGroup(int);
+ void setBaseInExpressionFromDialogBox(int);
+ void setBase();
+ void nonZeroDenominators(bool);
+ void warnAboutDenominatorsAssumedNonZero(bool);
+ void algebraicModeSimplify();
+ void algebraicModeFactorize();
+ void algebraicModeNone();
+ void readPrecision(bool);
+ void limitImplicitMultiplication(bool);
+ void setPrecision(int);
+ void precision();
+ void decimals();
+ void rpnMode(bool);
+ void rpnSyntax(bool);
+ void assumptionSignUnknown();
+ void assumptionSignNonZero();
+ void assumptionSignPositive();
+ void assumptionSignNonNegative();
+ void assumptionSignNegative();
+ void assumptionSignNonPositive();
+ void assumptionTypeUnknown();
+ void assumptionTypeNonMatrix();
+ void assumptionTypeNumber();
+ void assumptionTypeComplex();
+ void assumptionTypeReal();
+ void assumptionTypeRational();
+ void assumptionTypeInteger();
+ void loadMode(int);
+ void onModesMenuItemActivated(int);
+ void saveModeAs();
+ void deleteMode();
+ void saveMode();
+ void angleUnitDegrees();
+ void angleUnitRadians();
+ void angleUnitGradians();
+ void angleUnitNone();
+ void autoNoConversion();
+ void autoConvertToBaseUnits();
+ void autoConvertToBestUnit();
+ void enablePrefixes(bool);
+ void enableUseOfAllPrefixes(bool);
+ void enableDenominatorPrefixes(bool);
+ void placeUnitsSeparately(bool);
+ void enableVariables(bool);
+ void enableFunctions(bool);
+ void enableUnits(bool);
+ void enableUnknowns(bool);
+ void calculateVariables(bool);
+ void allowComplexResult(bool);
+ void allowInfiniteResult(bool);
+ void updateExchangeRates();
+ void insertKP1();
+ void insertKP2();
+ void insertKP3();
+ void insertKP4();
+ void insertKP5();
+ void insertKP6();
+ void insertKP7();
+ void insertKP8();
+ void insertKP9();
+ void insertKP0();
+ void insertDot();
+ void insertExp();
+ void insertAns();
+ void insertMinus();
+ void insertPlus();
+ void insertTimes();
+ void insertDivision();
+ void insertCos();
+ void insertSin();
+ void insertTan();
+ void insertSqrt();
+ void insertLog();
+ void insertLn();
+ void insertRaise();
+ void clearExpression();
+ void expressionDel();
+ void insertSquare();
+ void setExactMode(bool);
+ void setFractionMode(bool);
+ void kpSetAngleUnit(int);
+ void kpSetBaseSelected(int);
+ void kpSetBase(int);
+ void kpSetNumericalMode(int);
+ void insertFactorial();
+ void insertMod();
+ void storeResult();
+ void manageVariables();
+ void convertToUnitConvertToDialogExpression();
+ void convertToUnitExpression();
+ void convertNumberBases();
+ void insertManagedFunction(MathFunction*);
+ void applyManagedFunction(MathFunction*);
+ void manageFunctions();
+ void manageUnits();
+ void insertUnit(Unit *u);
+ void convertResult(Unit *u);
+ void factorize();
+ void simplify();
+ void manageDataSets();
+ void setUnknownsApplyClicked();
+ void setUnknowns();
+ void convertToBaseUnits();
+ void convertToBestUnit();
+ void copyResult();
+ void clearHistory();
+ void preferences();
+ void applyPreferences();
+ void onConvertToUnitMenuItemActivated(int);
+ void onSetPrefixMenuItemActivated(int);
+ void periodicTable();
+ void plotFunctionsData();
+ void saveDefinitions();
+ void saveAsImage();
+ void importCSVFile();
+ void exportCSVFile();
+ void newVariable();
+ void newMatrix();
+ void newVector();
+ void newUnknownVariable();
+ void newFunction();
+ void newDataSet();
+ void newUnit();
+ void insertMatrix();
+ void insertVector();
+ void showSystemTrayIcon(bool);
+ void hideSystemTrayIcon();
+ void displayParseStatus();
+ void registerUp();
+ void registerDown();
+ void clearStack();
+ void deleteRegister();
+ void editRegister();
+ void updateRPNIndexes();
+ QListViewItem *getRPNRegister(size_t index);
+ void stackRegisterMoved();
+ void stackRegisterSet(QListViewItem*);
+ void popupStackMenu(KListView*, QListViewItem*, const QPoint&);
+ void registerSelected();
+ void editHistoryExpression();
+ void editHistoryParse();
+ void editHistoryResult();
+ void insertHistoryResultVariable();
+
+protected:
+
+ void updateButtonWidths();
+ void applySetUnknowns(bool okclicked);
+ bool b_unknowns_changed;
+ QValueVector<bool> unknown_changed;
+ MathStructure *mstruct_before_unknowns, *unknowns_mstruct;
+ QValueVector<KLineEdit*> unknowns_entries;
+ bool queryClose();
+ QString parsed_expression;
+ void keyPressEvent(QKeyEvent *e);
+ void fontChange(const QFont &old_font);
+ void saveProperties(KConfig *cfg);
+ void readProperties(KConfig *cfg);
+
+private:
+
+ bool close_to_systray_was;
+ bool display_expression_status_was;
+ int history_height;
+
+};
+
+class QalculateHistoryBrowser : public KTextBrowser {
+
+ Q_OBJECT
+
+public:
+
+ QalculateHistoryBrowser(QWidget *parent, const char *name);
+ ~QalculateHistoryBrowser();
+
+protected:
+
+ QPopupMenu *createPopupMenu(const QPoint &pos);
+
+};
+
+class QalculateParseLabel : public QLabel {
+
+ Q_OBJECT
+
+public:
+
+ QalculateParseLabel(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateParseLabel();
+
+ void setText(QString text, bool break_begin, bool error_color, bool warning_color);
+
+protected:
+
+ QString parsetext;
+ bool bb, ec, wc;
+ void drawContents(QPainter *p);
+
+};
+
+class QalculateButton : public QPushButton {
+
+ Q_OBJECT
+
+public:
+
+ QalculateButton(QWidget *parent = 0, const char *name = 0);
+ QalculateButton(const QString &text, QWidget *parent = 0, const char *name = 0);
+ QalculateButton(const QIconSet &icon, const QString &text, QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateButton();
+
+ void setUseMinThreeCharWidth(bool b);
+ void setMarkup(const QString &str);
+ QSize sizeHint() const;
+
+private:
+
+ bool umtcw;
+
+};
+
+class QalculateStyleSheet : public QStyleSheet {
+
+ Q_OBJECT
+
+public:
+
+ QalculateStyleSheet(QObject *parent = 0, const char *name = 0);
+ virtual ~QalculateStyleSheet();
+
+ void scaleFont(QFont &font, int logicalSize) const;
+
+};
+
+class QalculateRPNStackListView : public KListView {
+
+ Q_OBJECT
+
+public:
+
+ QalculateRPNStackListView(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateRPNStackListView();
+
+protected:
+
+ void keyPressEvent(QKeyEvent *e);
+
+};
+
+class QalculateModeDialog : public KDialogBase {
+
+ Q_OBJECT
+
+ protected:
+
+ KKeyButton *keyButton;
+ KComboBox *modeCombo;
+
+ public:
+
+ QalculateModeDialog(QWidget *parent);
+ virtual ~QalculateModeDialog();
+
+ QString modeName();
+ const KShortcut &modeShortcut();
+
+ public slots:
+
+ void slotOk();
+ void updateShortcut(const KShortcut&);
+ void modeSelected(int);
+
+};
+
+#endif // QALCULATE_KWINDOW_H
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..157653f
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,306 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "kqalculate.h"
+#include "preferences.h"
+#include <kwin.h>
+#include <kuniqueapplication.h>
+#include <kaboutdata.h>
+#include <kcmdlineargs.h>
+#include <klocale.h>
+#include <unistd.h>
+#include <qtextcodec.h>
+#include <qobject.h>
+#include <kmessagebox.h>
+#include <qtimer.h>
+#include <klineedit.h>
+#include <qtooltip.h>
+#include <qclipboard.h>
+#include "qalculateexpressionedit.h"
+#include "qalculateresultdisplay.h"
+
+#include "qalculate_kde_utils.h"
+
+static const char description[] = I18N_NOOP("A powerful and easy to use desktop calculator");
+
+static const char version[] = VERSION;
+
+static KCmdLineOptions options[] = {
+ {"c", 0, 0},
+ {"clipboard", I18N_NOOP("Calculate X11-clipboard content (selected text)"), 0},
+ {"+[Expression]", I18N_NOOP( "Initial expression to calculate" ), 0},
+ KCmdLineLastOption
+};
+
+extern KnownVariable *vans[5];
+extern MathStructure *mstruct, *matrix_mstruct, *parsed_mstruct, *parsed_tostruct;
+extern QString result_text, result_history_text, parsed_text;
+extern QWidget *expressionWidget, *resultWidget, *statusWidget_l;
+extern QWidget *topWidget;
+extern KQalculate *mainWin;
+
+extern bool load_global_defs, fetch_exchange_rates_at_startup, first_time, first_qalculate_run;
+extern bool b_busy;
+extern bool canplot;
+extern bool close_to_systray;
+
+extern FILE *view_pipe_r, *view_pipe_w, *command_pipe_r, *command_pipe_w;
+extern pthread_t view_thread, command_thread;
+extern pthread_attr_t view_thread_attr, command_thread_attr;
+extern bool command_thread_started;
+
+extern QValueVector<QString> recent_functions_pre;
+extern QValueVector<QString> recent_variables_pre;
+extern QValueVector<QString> recent_units_pre;
+
+QTimer *error_timer;
+
+void create_qalculate_window(KUniqueApplication *parent) {
+
+ QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf8"));
+
+ b_busy = false;
+
+ new Calculator();
+ if(KGlobal::locale()->decimalSymbol() == ",") CALCULATOR->useDecimalComma();
+ CALCULATOR->place_currency_code_before = KGlobal::locale()->positivePrefixCurrencySymbol();
+
+ //load application specific preferences
+ load_preferences();
+
+ mstruct = new MathStructure();
+ parsed_mstruct = new MathStructure();
+ parsed_tostruct = new MathStructure();
+ parsed_tostruct->setUndefined();
+ matrix_mstruct = new MathStructure();
+
+ canplot = CALCULATOR->canPlot();
+
+ mainWin = new KQalculate(parent);
+ topWidget = mainWin;
+ expressionWidget = (QWidget*) mainWin->expressionEdit;
+ resultWidget = (QWidget*) mainWin->resultLabel;
+ statusWidget_l = (QWidget*) mainWin->statusLabel_l;
+
+}
+
+QString parse_expression_arguments(KCmdLineArgs *args) {
+ QString calc_arg;
+ if(args->isSet("clipboard")) {
+ calc_arg = qApp->clipboard()->text(QClipboard::Selection);
+ if(calc_arg.isEmpty()) {
+ calc_arg = qApp->clipboard()->text(QClipboard::Clipboard);
+ }
+ } else {
+ for(int i = 0; i < args->count(); i++) {
+ if(i > 0) {
+ calc_arg += " ";
+ }
+ calc_arg += args->arg(i);
+ }
+ }
+ return calc_arg;
+}
+
+void start_qalculate() {
+
+ KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
+ QString calc_arg = parse_expression_arguments(args);
+ args->clear();
+ if(!calc_arg.isEmpty()) {
+ mainWin->expressionEdit->setText(calc_arg);
+ } else if(first_time) {
+ mainWin->resultLabel->setText(i18n("Enter a mathematical expression above.<br>Ex. 5 + 2 / 3"));
+ } else {
+ mainWin->resultLabel->setText("<div align=\"right\"><font size=2>&nbsp;<br></font><font size=6>= 0</font></div>");
+ }
+
+ qApp->processEvents();
+
+ //exchange rates
+ if(first_qalculate_run) {
+ if(KMessageBox::questionYesNo(mainWin, i18n("You need to download exchange rates to be able to convert between different currencies. You can later get current exchange rates by selecting \"Update Exchange Rates\" under the File menu.\n\nDo you want to fetch exchange rates now from the Internet?"), i18n("Update exchange rates?")) == KMessageBox::Yes) {
+ qApp->processEvents();
+ mainWin->fetch_exchange_rates(5);
+ }
+ qApp->processEvents();
+ } else if(fetch_exchange_rates_at_startup) {
+ mainWin->fetch_exchange_rates(5);
+ qApp->processEvents();
+ }
+
+ CALCULATOR->loadExchangeRates();
+
+ string ans_str = i18n("ans").ascii();
+ vans[0] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str, m_undefined, i18n("Last Answer").ascii(), false));
+ vans[0]->addName(i18n("answer").ascii());
+ vans[0]->addName(ans_str + "1");
+ vans[1] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "2", m_undefined, i18n("Answer 2").ascii(), false));
+ vans[2] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "3", m_undefined, i18n("Answer 3").ascii(), false));
+ vans[3] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "4", m_undefined, i18n("Answer 4").ascii(), false));
+ vans[4] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "5", m_undefined, i18n("Answer 5").ascii(), false));
+
+ //load global definitions
+ if(load_global_defs && !CALCULATOR->loadGlobalDefinitions()) {
+ KMessageBox::error(mainWin, i18n("Failed to load global definitions!"), i18n("Error"));
+ qApp->processEvents();
+ }
+
+ //load local definitions
+ CALCULATOR->loadLocalDefinitions();
+
+ //check for calculation errros regularly
+ error_timer = new QTimer(mainWin);
+ QObject::connect(error_timer, SIGNAL(timeout()), mainWin, SLOT(onErrorTimeout()));
+
+ generate_units_tree_struct();
+ generate_functions_tree_struct();
+ generate_variables_tree_struct();
+ mainWin->create_fmenu();
+ mainWin->create_vmenu();
+ mainWin->create_umenu();
+ mainWin->create_toumenu();
+ mainWin->create_setpmenu();
+
+ for(int i = ((int) recent_functions_pre.size()) - 1; i >= 0; i--) {
+ mainWin->function_inserted(CALCULATOR->getActiveFunction(recent_functions_pre[i].ascii()));
+ }
+ for(int i = ((int) recent_variables_pre.size()) - 1; i >= 0; i--) {
+ mainWin->variable_inserted(CALCULATOR->getActiveVariable(recent_variables_pre[i].ascii()));
+ }
+ for(int i = ((int) recent_units_pre.size()) - 1; i >= 0; i--) {
+ Unit *u = CALCULATOR->getActiveUnit(recent_units_pre[i].ascii());
+ if(!u) u = CALCULATOR->getCompositeUnit(recent_units_pre[i].ascii());
+ mainWin->unit_inserted(u);
+ }
+
+ mainWin->update_completion();
+
+ int pipe_wr[] = {0, 0};
+ pipe(pipe_wr);
+ view_pipe_r = fdopen(pipe_wr[0], "r");
+ view_pipe_w = fdopen(pipe_wr[1], "w");
+ pthread_attr_init(&view_thread_attr);
+ pthread_create(&view_thread, &view_thread_attr, view_proc, view_pipe_r);
+
+ int pipe_wr2[] = {0, 0};
+ pipe(pipe_wr2);
+ command_pipe_r = fdopen(pipe_wr2[0], "r");
+ command_pipe_w = fdopen(pipe_wr2[1], "w");
+ pthread_attr_init(&command_thread_attr);
+ command_thread_started = false;
+
+ QObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()));
+ QObject::connect(qApp, SIGNAL(aboutToQuit()), mainWin, SLOT(aboutToQuit()));
+
+ error_timer->start(100);
+
+ if(!calc_arg.isEmpty()) {
+ mainWin->execute_expression();
+ }
+
+}
+
+class QalculateApp : public KUniqueApplication {
+
+public:
+
+ bool started;
+
+ QalculateApp() {started = false;}
+ virtual ~QalculateApp() {}
+
+ int newInstance() {
+ if(mainWin && started) {
+
+ KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
+ QString calc_arg = parse_expression_arguments(args);
+ args->clear();
+
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ KWin::Info info = KWin::info(mainWin->winId());
+ KWin::setOnDesktop(mainWin->winId(), KWin::currentDesktop());
+ mainWin->move(info.geometry.topLeft());
+#else
+ KWin::WindowInfo info = KWin::windowInfo(mainWin->winId(), (unsigned long) NET::WMGeometry);
+ KWin::setOnDesktop(mainWin->winId(), KWin::currentDesktop());
+ mainWin->move(info.geometry().topLeft());
+#endif
+ mainWin->setShown(true);
+ mainWin->show();
+ mainWin->raise();
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ KWin::setActiveWindow(mainWin->winId());
+#else
+ KWin::activateWindow(mainWin->winId());
+#endif
+
+ if(!calc_arg.isEmpty()) {
+ mainWin->expressionEdit->setText(calc_arg);
+ mainWin->execute_expression();
+ }
+
+ return 0;
+ } else {
+ if(isRestored() && KMainWindow::canBeRestored(1)) {
+ create_qalculate_window(this);
+ setMainWidget(mainWin);
+ mainWin->restore(1, false);
+ start_qalculate();
+ } else {
+ create_qalculate_window(this);
+ setMainWidget(mainWin);
+ mainWin->show();
+ start_qalculate();
+ }
+ started = true;
+ return KUniqueApplication::newInstance();
+ }
+ started = true;
+ return 0;
+ }
+
+};
+
+int main(int argc, char **argv) {
+
+ mainWin = NULL;
+
+ KAboutData about(PACKAGE, I18N_NOOP("Qalculate!"), version, description, KAboutData::License_GPL, "(C) 2005-2006 Niklas Knutsson", 0, "http://qalculate.sourceforge.net/", "nique769@users.sourceforge.net");
+ about.addAuthor("Niklas Knutsson", 0, "nq@altern.org");
+ KCmdLineArgs::init(argc, argv, &about);
+ KCmdLineArgs::addCmdLineOptions(options);
+ KUniqueApplication::addCmdLineOptions();
+
+ if(!QalculateApp::start()) {
+ return 0;
+ }
+
+ QalculateApp app;
+
+ return app.exec();
+
+}
+
+
diff --git a/src/preferences.cpp b/src/preferences.cpp
new file mode 100644
index 0000000..658e5ec
--- /dev/null
+++ b/src/preferences.cpp
@@ -0,0 +1,865 @@
+/***************************************************************************
+ * Copyright (C) 2005-2007 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "preferences.h"
+#include "kqalculate.h"
+#include "qalculate_kde_utils.h"
+#include "qalculateexpressionedit.h"
+#include <sys/stat.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <klocale.h>
+#include <qstringlist.h>
+#include <ktextbrowser.h>
+#include <qwidgetstack.h>
+#include <qpushbutton.h>
+#include <qvaluevector.h>
+
+PrintOptions printops;
+EvaluationOptions evalops;
+bool rpn_mode;
+bool rpn_keypad_only;
+bool load_global_defs, fetch_exchange_rates_at_startup, first_time, first_qalculate_run, save_mode_on_exit, save_defs_on_exit;
+bool use_custom_result_font, use_custom_expression_font, use_custom_status_font;
+int use_icon_buttons;
+QString custom_result_font, custom_expression_font, custom_status_font;
+QColor status_warning_color, status_error_color;
+
+bool display_expression_status;
+bool close_to_systray;
+bool enable_expression_completion;
+
+PlotLegendPlacement default_plot_legend_placement;
+bool default_plot_display_grid;
+bool default_plot_full_border;
+QString default_plot_min;
+QString default_plot_max;
+QString default_plot_step;
+int default_plot_sampling_rate;
+bool default_plot_use_sampling_rate;
+bool default_plot_rows;
+int default_plot_type;
+PlotStyle default_plot_style;
+PlotSmoothing default_plot_smoothing;
+QString default_plot_variable;
+bool default_plot_color;
+bool enable_plot_expression_completion;
+
+bool canplot;
+
+QString initial_history;
+
+extern vector<MathFunction*> recent_functions;
+extern vector<Variable*> recent_variables;
+extern vector<Unit*> recent_units;
+QValueVector<QString> recent_functions_pre;
+QValueVector<QString> recent_variables_pre;
+QValueVector<QString> recent_units_pre;
+
+extern QWidget *expressionWidget;
+extern KQalculate *mainWin;
+QStringList expression_history;
+
+bool show_keypad, show_history, show_stack;
+
+vector<mode_struct> modes;
+
+QValueVector<QString> inhistory;
+QValueVector<int> inhistory_type;
+QValueVector<int> inhistory_id;
+int inhistory_current_id;
+
+/*
+ save mode to file
+*/
+void save_mode() {
+ return save_preferences(true);
+}
+
+/*
+ remember current mode
+*/
+void set_saved_mode() {
+ modes[1].precision = CALCULATOR->getPrecision();
+ modes[1].po = printops;
+ modes[1].po.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
+ modes[1].eo = evalops;
+ modes[1].at = CALCULATOR->defaultAssumptions()->type();
+ modes[1].as = CALCULATOR->defaultAssumptions()->sign();
+ modes[1].rpn_mode = rpn_mode;
+}
+
+size_t save_mode_as(QString name, bool *new_mode) {
+ name = name.stripWhiteSpace();
+ size_t index = 0;
+ for(; index < modes.size(); index++) {
+ if(modes[index].name == name) {
+ if(new_mode) *new_mode = false;
+ break;
+ }
+ }
+ if(index >= modes.size()) {
+ modes.resize(modes.size() + 1);
+ index = modes.size() - 1;
+ if(new_mode) *new_mode = true;
+ }
+ modes[index].po = printops;
+ modes[index].po.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
+ modes[index].eo = evalops;
+ modes[index].precision = CALCULATOR->getPrecision();
+ modes[index].at = CALCULATOR->defaultAssumptions()->type();
+ modes[index].as = CALCULATOR->defaultAssumptions()->sign();
+ modes[index].name = name;
+ modes[index].rpn_mode = rpn_mode;
+ return index;
+}
+
+void load_preferences() {
+
+ default_plot_legend_placement = PLOT_LEGEND_TOP_RIGHT;
+ default_plot_display_grid = true;
+ default_plot_full_border = false;
+ default_plot_min = "0";
+ default_plot_max = "10";
+ default_plot_step = "1";
+ default_plot_sampling_rate = 100;
+ default_plot_rows = false;
+ default_plot_type = 0;
+ default_plot_style = PLOT_STYLE_LINES;
+ default_plot_smoothing = PLOT_SMOOTHING_NONE;
+ default_plot_variable = "x";
+ default_plot_color = true;
+ default_plot_use_sampling_rate = true;
+
+ printops.is_approximate = new bool(false);
+ printops.prefix = NULL;
+ printops.use_min_decimals = false;
+ printops.use_denominator_prefix = true;
+ printops.min_decimals = 0;
+ printops.use_max_decimals = false;
+ printops.max_decimals = 2;
+ printops.base = 10;
+ printops.min_exp = EXP_PRECISION;
+ printops.negative_exponents = false;
+ printops.sort_options.minus_last = true;
+ printops.indicate_infinite_series = false;
+ printops.show_ending_zeroes = false;
+ printops.round_halfway_to_even = false;
+ printops.number_fraction_format = FRACTION_DECIMAL;
+ printops.abbreviate_names = true;
+ printops.use_unicode_signs = true;
+ printops.use_unit_prefixes = true;
+ printops.spacious = true;
+ printops.short_multiplication = true;
+ printops.limit_implicit_multiplication = false;
+ printops.place_units_separately = true;
+ printops.use_all_prefixes = false;
+ printops.excessive_parenthesis = false;
+ printops.allow_non_usable = false;
+ printops.lower_case_numbers = false;
+ printops.lower_case_e = false;
+ printops.base_display = BASE_DISPLAY_NORMAL;
+ printops.division_sign = DIVISION_SIGN_DIVISION_SLASH;
+ printops.multiplication_sign = MULTIPLICATION_SIGN_DOT;
+ printops.can_display_unicode_string_function = &can_display_unicode_string_function;
+ printops.allow_factorization = false;
+ printops.spell_out_logical_operators = true;
+
+ evalops.parse_options.limit_implicit_multiplication = false;
+ evalops.approximation = APPROXIMATION_TRY_EXACT;
+ evalops.sync_units = true;
+ evalops.structuring = STRUCTURING_SIMPLIFY;
+ evalops.parse_options.unknowns_enabled = false;
+ evalops.parse_options.read_precision = DONT_READ_PRECISION;
+ evalops.parse_options.base = BASE_DECIMAL;
+ evalops.allow_complex = true;
+ evalops.allow_infinite = true;
+ evalops.auto_post_conversion = POST_CONVERSION_NONE;
+ evalops.assume_denominators_nonzero = true;
+ evalops.warn_about_denominators_assumed_nonzero = true;
+ evalops.parse_options.angle_unit = ANGLE_UNIT_RADIANS;
+ evalops.parse_options.dot_as_separator = KGlobal::locale()->thousandsSeparator() == ".";
+
+ rpn_mode = false;
+ rpn_keypad_only = true;
+
+ save_mode_as(i18n("Preset"));
+ save_mode_as(i18n("Default"));
+ size_t mode_index = 1;
+
+ inhistory_current_id = 0;
+
+ status_warning_color.setNamedColor("blue");
+ status_error_color.setNamedColor("red");
+ use_icon_buttons = 1;
+ enable_expression_completion = true;
+ enable_plot_expression_completion = true;
+ close_to_systray = false;
+ show_keypad = true;
+ show_history = false;
+ show_stack = true;
+ display_expression_status = true;
+ save_mode_on_exit = true;
+ save_defs_on_exit = true;
+ use_custom_result_font = false;
+ use_custom_expression_font = false;
+ use_custom_status_font = false;
+ custom_result_font = "";
+ custom_expression_font = "";
+ custom_status_font = "";
+ load_global_defs = true;
+ fetch_exchange_rates_at_startup = false;
+ first_time = false;
+ string filename = getLocalDir();
+ DIR *dir = opendir(filename.c_str());
+ if(!dir) {
+ first_qalculate_run = true;
+ first_time = true;
+ set_saved_mode();
+ return;
+ } else {
+ first_qalculate_run = false;
+ closedir(dir);
+ }
+
+ int version_numbers[] = {0, 9, 6};
+ FILE *file = NULL;
+ filename += "qalculate-kde.cfg";
+ file = fopen(filename.c_str(), "r");
+ if(file) {
+ char line[10000];
+ QString stmp, svalue, svar;
+ int i;
+ int v;
+ while(true) {
+ if(fgets(line, 10000, file) == NULL)
+ break;
+ stmp = line;
+ stmp = stmp.stripWhiteSpace();
+ if((i = stmp.find("=")) >= 0) {
+ svar = stmp;
+ svar.truncate(i);
+ svar = svar.stripWhiteSpace();
+ svalue = stmp;
+ svalue.remove(0, i + 1);
+ svalue = svalue.stripWhiteSpace();
+ v = svalue.toInt();
+ if(svar == "version") {
+ parse_qalculate_version(svalue.ascii(), version_numbers);
+ } else if(svar == "shortcut") {
+ if(mode_index != 1) modes[mode_index].shortcut.init(svalue);
+ } else if(svar == "save_mode_on_exit") {
+ save_mode_on_exit = v;
+ } else if(svar == "save_definitions_on_exit") {
+ save_defs_on_exit = v;
+ } else if(svar == "fetch_exchange_rates_at_startup") {
+ fetch_exchange_rates_at_startup = v;
+ } else if(svar == "min_deci") {
+ if(mode_index == 1) printops.min_decimals = v;
+ else modes[mode_index].po.min_decimals = v;
+ } else if(svar == "use_min_deci") {
+ if(mode_index == 1) printops.use_min_decimals = v;
+ else modes[mode_index].po.use_min_decimals = v;
+ } else if(svar == "max_deci") {
+ if(mode_index == 1) printops.max_decimals = v;
+ else modes[mode_index].po.max_decimals = v;
+ } else if(svar == "use_max_deci") {
+ if(mode_index == 1) printops.use_max_decimals = v;
+ else modes[mode_index].po.use_max_decimals = v;
+ } else if(svar == "precision") {
+ if(mode_index == 1) CALCULATOR->setPrecision(v);
+ else modes[mode_index].precision = v;
+ } else if(svar == "min_exp") {
+ if(mode_index == 1) printops.min_exp = v;
+ else modes[mode_index].po.min_exp = v;
+ } else if(svar == "negative_exponents") {
+ if(mode_index == 1) printops.negative_exponents = v;
+ else modes[mode_index].po.negative_exponents = v;
+ } else if(svar == "sort_minus_last") {
+ if(mode_index == 1) printops.sort_options.minus_last = v;
+ else modes[mode_index].po.sort_options.minus_last = v;
+ } else if(svar == "place_units_separately") {
+ if(mode_index == 1) printops.place_units_separately = v;
+ else modes[mode_index].po.place_units_separately = v;
+ } else if(svar == "use_prefixes") {
+ if(mode_index == 1) printops.use_unit_prefixes = v;
+ else modes[mode_index].po.use_unit_prefixes = v;
+ } else if(svar == "number_fraction_format") {
+ if(v >= FRACTION_DECIMAL && v <= FRACTION_COMBINED) {
+ if(mode_index == 1) printops.number_fraction_format = (NumberFractionFormat) v;
+ else modes[mode_index].po.number_fraction_format = (NumberFractionFormat) v;
+ }
+ } else if(svar == "number_base") {
+ if(mode_index == 1) printops.base = v;
+ else modes[mode_index].po.base = v;
+ } else if(svar == "number_base_expression") {
+ if(mode_index == 1) evalops.parse_options.base = v;
+ else modes[mode_index].eo.parse_options.base = v;
+ } else if(svar == "read_precision") {
+ if(v >= DONT_READ_PRECISION && v <= READ_PRECISION_WHEN_DECIMALS) {
+ if(mode_index == 1) evalops.parse_options.read_precision = (ReadPrecisionMode) v;
+ else modes[mode_index].eo.parse_options.read_precision = (ReadPrecisionMode) v;
+ }
+ } else if(svar == "assume_denominators_nonzero") {
+ if(version_numbers[0] == 0 && (version_numbers[1] < 9 || (version_numbers[1] == 9 && version_numbers[2] == 0))) {
+ v = true;
+ }
+ if(mode_index == 1) evalops.assume_denominators_nonzero = v;
+ else modes[mode_index].eo.assume_denominators_nonzero = v;
+ } else if(svar == "warn_about_denominators_assumed_nonzero") {
+ if(mode_index == 1) evalops.warn_about_denominators_assumed_nonzero = v;
+ else modes[mode_index].eo.warn_about_denominators_assumed_nonzero = v;
+ } else if(svar == "structuring") {
+ if(v >= STRUCTURING_NONE && v <= STRUCTURING_FACTORIZE) {
+ if(mode_index == 1) {
+ evalops.structuring = (StructuringMode) v;
+ printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
+ } else {
+ modes[mode_index].eo.structuring = (StructuringMode) v;
+ modes[mode_index].po.allow_factorization = (modes[mode_index].eo.structuring == STRUCTURING_FACTORIZE);
+ }
+ }
+ } else if(svar == "angle_unit") {
+ if(v >= ANGLE_UNIT_NONE && v <= ANGLE_UNIT_GRADIANS) {
+ if(mode_index == 1) evalops.parse_options.angle_unit = (AngleUnit) v;
+ else modes[mode_index].eo.parse_options.angle_unit = (AngleUnit) v;
+ }
+ } else if(svar == "functions_enabled") {
+ if(mode_index == 1) evalops.parse_options.functions_enabled = v;
+ else modes[mode_index].eo.parse_options.functions_enabled = v;
+ } else if(svar == "variables_enabled") {
+ if(mode_index == 1) evalops.parse_options.variables_enabled = v;
+ else modes[mode_index].eo.parse_options.variables_enabled = v;
+ } else if(svar == "calculate_variables") {
+ if(mode_index == 1) evalops.calculate_variables = v;
+ else modes[mode_index].eo.calculate_variables = v;
+ } else if(svar == "calculate_functions") {
+ if(mode_index == 1) evalops.calculate_functions = v;
+ else modes[mode_index].eo.calculate_functions = v;
+ } else if(svar == "sync_units") {
+ if(mode_index == 1) evalops.sync_units = v;
+ else modes[mode_index].eo.sync_units = v;
+ } else if(svar == "unknownvariables_enabled") {
+ if(mode_index == 1) evalops.parse_options.unknowns_enabled = v;
+ else modes[mode_index].eo.parse_options.unknowns_enabled = v;
+ } else if(svar == "units_enabled") {
+ if(mode_index == 1) evalops.parse_options.units_enabled = v;
+ else modes[mode_index].eo.parse_options.units_enabled = v;
+ } else if(svar == "allow_complex") {
+ if(mode_index == 1) evalops.allow_complex = v;
+ else modes[mode_index].eo.allow_complex = v;
+ } else if(svar == "allow_infinite") {
+ if(mode_index == 1) evalops.allow_infinite = v;
+ else modes[mode_index].eo.allow_infinite = v;
+ } else if(svar == "use_short_units") {
+ if(mode_index == 1) printops.abbreviate_names = v;
+ else modes[mode_index].po.abbreviate_names = v;
+ } else if(svar == "abbreviate_names") {
+ if(mode_index == 1) printops.abbreviate_names = v;
+ else modes[mode_index].po.abbreviate_names = v;
+ } else if(svar == "all_prefixes_enabled") {
+ if(mode_index == 1) printops.use_all_prefixes = v;
+ else modes[mode_index].po.use_all_prefixes = v;
+ } else if(svar == "denominator_prefix_enabled") {
+ if(mode_index == 1) printops.use_denominator_prefix = v;
+ else modes[mode_index].po.use_denominator_prefix = v;
+ } else if(svar == "auto_post_conversion") {
+ if(v >= POST_CONVERSION_NONE && v <= POST_CONVERSION_BASE) {
+ if(mode_index == 1) evalops.auto_post_conversion = (AutoPostConversion) v;
+ else modes[mode_index].eo.auto_post_conversion = (AutoPostConversion) v;
+ }
+ } else if(svar == "indicate_infinite_series") {
+ if(mode_index == 1) printops.indicate_infinite_series = v;
+ else modes[mode_index].po.indicate_infinite_series = v;
+ } else if(svar == "show_ending_zeroes") {
+ if(mode_index == 1) printops.show_ending_zeroes = v;
+ else modes[mode_index].po.show_ending_zeroes = v;
+ } else if(svar == "round_halfway_to_even") {
+ if(mode_index == 1) printops.round_halfway_to_even = v;
+ else modes[mode_index].po.round_halfway_to_even = v;
+ } else if(svar == "approximation") {
+ if(v >= APPROXIMATION_EXACT && v <= APPROXIMATION_APPROXIMATE) {
+ if(mode_index == 1) evalops.approximation = (ApproximationMode) v;
+ else modes[mode_index].eo.approximation = (ApproximationMode) v;
+ }
+ } else if(svar == "in_rpn_mode") {
+ if(mode_index == 1) rpn_mode = v;
+ else modes[mode_index].rpn_mode = v;
+ } else if(svar == "rpn_keypad_only") {
+ rpn_keypad_only = v;
+ } else if(svar == "rpn_syntax") {
+ if(mode_index == 1) evalops.parse_options.rpn = v;
+ else modes[mode_index].eo.parse_options.rpn = v;
+ } else if(svar == "limit_implicit_multiplication") {
+ if(mode_index == 1) {
+ evalops.parse_options.limit_implicit_multiplication = v;
+ printops.limit_implicit_multiplication = v;
+ } else {
+ modes[mode_index].eo.parse_options.limit_implicit_multiplication = v;
+ modes[mode_index].po.limit_implicit_multiplication = v;
+ }
+ } else if(svar == "default_assumption_type") {
+ if(v >= ASSUMPTION_TYPE_NONE && v <= ASSUMPTION_TYPE_INTEGER) {
+ if(v == ASSUMPTION_TYPE_NONE && version_numbers[0] == 0 && (version_numbers[1] < 9 || (version_numbers[1] == 9 && version_numbers[2] == 0))) {
+ v = ASSUMPTION_TYPE_NONMATRIX;
+ }
+ if(mode_index == 1) CALCULATOR->defaultAssumptions()->setType((AssumptionType) v);
+ else modes[mode_index].at = (AssumptionType) v;
+ }
+ } else if(svar == "default_assumption_sign") {
+ if(v >= ASSUMPTION_SIGN_UNKNOWN && v <= ASSUMPTION_SIGN_NONZERO) {
+ if(v == ASSUMPTION_SIGN_NONZERO && version_numbers[0] == 0 && (version_numbers[1] < 9 || (version_numbers[1] == 9 && version_numbers[2] == 0))) {
+ v = ASSUMPTION_SIGN_UNKNOWN;
+ }
+ if(mode_index == 1) CALCULATOR->defaultAssumptions()->setSign((AssumptionSign) v);
+ else modes[mode_index].as = (AssumptionSign) v;
+ }
+ } else if(svar == "spacious") {
+ if(mode_index == 1) printops.spacious = v;
+ else modes[mode_index].po.spacious = v;
+ } else if(svar == "excessive_parenthesis") {
+ if(mode_index == 1) printops.excessive_parenthesis = v;
+ else modes[mode_index].po.excessive_parenthesis = v;
+ } else if(svar == "short_multiplication") {
+ if(mode_index == 1) printops.short_multiplication = v;
+ else modes[mode_index].po.short_multiplication = v;
+ } else if(svar == "use_unicode_signs") {
+ printops.use_unicode_signs = v;
+ } else if(svar == "lower_case_numbers") {
+ printops.lower_case_numbers = v;
+ } else if(svar == "lower_case_e") {
+ printops.lower_case_e = v;
+ } else if(svar == "base_display") {
+ if(v >= BASE_DISPLAY_NONE && v <= BASE_DISPLAY_ALTERNATIVE) printops.base_display = (BaseDisplay) v;
+ } else if(svar == "spell_out_logical_operators") {
+ printops.spell_out_logical_operators = v;
+ } else if(svar == "dot_as_separator") {
+ evalops.parse_options.dot_as_separator = v;
+ } else if(svar == "use_custom_result_font") {
+ use_custom_result_font = v;
+ } else if(svar == "use_custom_expression_font") {
+ use_custom_expression_font = v;
+ } else if(svar == "use_custom_status_font") {
+ use_custom_status_font = v;
+ } else if(svar == "custom_result_font") {
+ custom_result_font = svalue;
+ } else if(svar == "custom_expression_font") {
+ custom_expression_font = svalue;
+ } else if(svar == "custom_status_font") {
+ custom_status_font = svalue;
+ } else if(svar == "status_error_color") {
+ status_error_color.setNamedColor(svalue);
+ } else if(svar == "status_warning_color") {
+ status_warning_color.setNamedColor(svalue);
+ } else if(svar == "multiplication_sign") {
+ if(v >= MULTIPLICATION_SIGN_ASTERISK && v <= MULTIPLICATION_SIGN_X) printops.multiplication_sign = (MultiplicationSign) v;
+ } else if(svar == "division_sign") {
+ if(v >= DIVISION_SIGN_SLASH && v <= DIVISION_SIGN_DIVISION) printops.division_sign = (DivisionSign) v;
+ } else if(svar == "close_to_system_tray") {
+ close_to_systray = v;
+ } else if(svar == "show_keypad") {
+ show_keypad = v;
+ } else if(svar == "show_history") {
+ show_history = v;
+ } else if(svar == "show_stack") {
+ show_stack = v;
+ } else if(svar == "display_expression_status") {
+ display_expression_status = v;
+ } else if(svar == "enable_expression_completion") {
+ enable_expression_completion = v;
+ } else if(svar == "use_icon_buttons") {
+ use_icon_buttons = v;
+ } else if(svar == "plot_legend_placement") {
+ if(v >= PLOT_LEGEND_NONE && v <= PLOT_LEGEND_OUTSIDE) default_plot_legend_placement = (PlotLegendPlacement) v;
+ } else if(svar == "plot_style") {
+ if(v >= PLOT_STYLE_LINES && v <= PLOT_STYLE_DOTS) default_plot_style = (PlotStyle) v;
+ } else if(svar == "plot_smoothing") {
+ if(v >= PLOT_SMOOTHING_NONE && v <= PLOT_SMOOTHING_SBEZIER) default_plot_smoothing = (PlotSmoothing) v;
+ } else if(svar == "plot_display_grid") {
+ default_plot_display_grid = v;
+ } else if(svar == "plot_full_border") {
+ default_plot_full_border = v;
+ } else if(svar == "plot_min") {
+ default_plot_min = svalue;
+ } else if(svar == "plot_max") {
+ default_plot_max = svalue;
+ } else if(svar == "plot_step") {
+ default_plot_step = svalue;
+ } else if(svar == "plot_sampling_rate") {
+ default_plot_sampling_rate = v;
+ } else if(svar == "plot_use_sampling_rate") {
+ default_plot_use_sampling_rate = v;
+ } else if(svar == "plot_variable") {
+ default_plot_variable = svalue;
+ } else if(svar == "plot_rows") {
+ default_plot_rows = v;
+ } else if(svar == "plot_type") {
+ default_plot_type = v;
+ } else if(svar == "plot_color") {
+ default_plot_color = v;
+ } else if(svar == "enable_plot_expression_completion") {
+ enable_plot_expression_completion = v;
+ } else if(svar == "expression_history") {
+ expression_history.push_back(svalue);
+ } else if(svar == "history") {
+ initial_history = svalue;
+ if(version_numbers[1] < 9) {
+ initial_history.replace("<br><br>", "<br><hr>");
+ }
+ inhistory.push_back(initial_history);
+ inhistory_type.push_back(QALCULATE_HISTORY_OLD);
+ } else if(svar == "history_old") {
+ inhistory.push_back(svalue);
+ inhistory_type.push_back(QALCULATE_HISTORY_OLD);
+ } else if(svar == "history_expression") {
+ inhistory.push_back(svalue);
+ inhistory_type.push_back(QALCULATE_HISTORY_EXPRESSION);
+ } else if(svar == "history_transformation") {
+ inhistory.push_back(svalue);
+ inhistory_type.push_back(QALCULATE_HISTORY_TRANSFORMATION);
+ } else if(svar == "history_result") {
+ inhistory.push_back(svalue);
+ inhistory_type.push_back(QALCULATE_HISTORY_RESULT);
+ } else if(svar == "history_result_approximate") {
+ inhistory.push_back(svalue);
+ inhistory_type.push_back(QALCULATE_HISTORY_RESULT_APPROXIMATE);
+ } else if(svar == "history_parse") {
+ inhistory.push_back(svalue);
+ inhistory_type.push_back(QALCULATE_HISTORY_PARSE);
+ } else if(svar == "history_parse_approximate") {
+ inhistory.push_back(svalue);
+ inhistory_type.push_back(QALCULATE_HISTORY_PARSE_APPROXIMATE);
+ } else if(svar == "history_register_moved") {
+ inhistory.push_back(svalue);
+ inhistory_type.push_back(QALCULATE_HISTORY_REGISTER_MOVED);
+ } else if(svar == "history_warning") {
+ inhistory.push_back(svalue);
+ inhistory_type.push_back(QALCULATE_HISTORY_WARNING);
+ } else if(svar == "history_error") {
+ inhistory.push_back(svalue);
+ inhistory_type.push_back(QALCULATE_HISTORY_ERROR);
+ } else if(svar == "history_continued") {
+ if(inhistory.size() > 0) {
+ inhistory[inhistory.size() - 1] += "<br>";
+ inhistory[inhistory.size() - 1] += svalue;
+ }
+ } else if(svar == "recent_functions") {
+ int v_i = 0;
+ while(true) {
+ v_i = svalue.find(',');
+ if(v_i < 0) {
+ svar = svalue.stripWhiteSpace();
+ if(!svar.isEmpty()) {
+ recent_functions_pre.push_back(svar);
+ }
+ break;
+ } else {
+ svar = svalue;
+ svar.truncate(v_i);
+ svalue.remove(0, v_i + 1);
+ svar = svar.stripWhiteSpace();
+ if(!svar.isEmpty()) {
+ recent_functions_pre.push_back(svar);
+ }
+ }
+ }
+ } else if(svar == "recent_variables") {
+ int v_i = 0;
+ while(true) {
+ v_i = svalue.find(',');
+ if(v_i < 0) {
+ svar = svalue.stripWhiteSpace();
+ if(!svar.isEmpty()) {
+ recent_variables_pre.push_back(svar);
+ }
+ break;
+ } else {
+ svar = svalue;
+ svar.truncate(v_i);
+ svalue.remove(0, v_i + 1);
+ svar = svar.stripWhiteSpace();
+ if(!svar.isEmpty()) {
+ recent_variables_pre.push_back(svar);
+ }
+ }
+ }
+ } else if(svar == "recent_units") {
+ int v_i = 0;
+ while(true) {
+ v_i = svalue.find(',');
+ if(v_i < 0) {
+ svar = svalue.stripWhiteSpace();
+ if(!svar.isEmpty()) {
+ recent_units_pre.push_back(svar);
+ }
+ break;
+ } else {
+ svar = svalue;
+ svar.truncate(v_i);
+ svalue.remove(0, v_i + 1);
+ svar = svar.stripWhiteSpace();
+ if(!svar.isEmpty()) {
+ recent_units_pre.push_back(svar);
+ }
+ }
+ }
+ }
+ } else if(stmp.length() > 2 && stmp[0] == '[' && stmp[stmp.length() - 1] == ']') {
+ stmp.truncate(stmp.length() - 1);
+ stmp.remove(0, 1);
+ stmp = stmp.stripWhiteSpace();
+ if(stmp == "Mode") {
+ mode_index = 1;
+ } else if(stmp.length() > 5) {
+ QString svar = stmp;
+ svar.truncate(4);
+ if(svar == "Mode") {
+ stmp.remove(0, 5);
+ mode_index = save_mode_as(stmp);
+ }
+ }
+ }
+ }
+ inhistory_current_id = (int) inhistory.size();
+ int id = inhistory_current_id;
+ id--;
+ for(QValueVector<QString>::size_type i = 0; i < inhistory.size(); i++) {
+ inhistory_id.push_back(id);
+ id--;
+ }
+ } else {
+ first_time = true;
+ }
+ if(show_keypad) show_history = false;
+ //remember start mode for when we save preferences
+ set_saved_mode();
+
+}
+
+void save_preferences(bool mode) {
+
+ FILE *file = NULL;
+ string filename = getLocalDir();
+ mkdir(filename.c_str(), S_IRWXU);
+ filename += "qalculate-kde.cfg";
+ file = fopen(filename.c_str(), "w+");
+ if(file == NULL) {
+ fprintf(stderr, i18n("Couldn't write preferences to\n%s"), filename.c_str());
+ return;
+ }
+ fprintf(file, "\n[General]\n");
+ fprintf(file, "version=%s\n", VERSION);
+ fprintf(file, "save_mode_on_exit=%i\n", save_mode_on_exit);
+ fprintf(file, "save_definitions_on_exit=%i\n", save_defs_on_exit);
+ fprintf(file, "load_global_definitions=%i\n", load_global_defs);
+ fprintf(file, "fetch_exchange_rates_at_startup=%i\n", fetch_exchange_rates_at_startup);
+ fprintf(file, "close_to_system_tray=%i\n", close_to_systray);
+ fprintf(file, "show_keypad=%i\n", mainWin->keypadButton->isOn() || (rpn_mode && show_keypad && mainWin->stackButton->isOn()));
+ fprintf(file, "show_history=%i\n", mainWin->historyButton->isOn() || (rpn_mode && show_history && mainWin->stackButton->isOn()));
+ fprintf(file, "show_stack=%i\n", rpn_mode ? mainWin->stackButton->isOn() : show_stack);
+ fprintf(file, "rpn_keypad_only=%i\n", rpn_keypad_only);
+ fprintf(file, "display_expression_status=%i\n", display_expression_status);
+ fprintf(file, "enable_expression_completion=%i\n", ((QalculateExpressionEdit*) expressionWidget)->completionEnabled());
+ if(use_icon_buttons >= 0) fprintf(file, "use_icon_buttons=%i\n", use_icon_buttons);
+ fprintf(file, "use_unicode_signs=%i\n", printops.use_unicode_signs);
+ fprintf(file, "lower_case_numbers=%i\n", printops.lower_case_numbers);
+ fprintf(file, "lower_case_e=%i\n", printops.lower_case_e);
+ fprintf(file, "base_display=%i\n", printops.base_display);
+ fprintf(file, "spell_out_logical_operators=%i\n", printops.spell_out_logical_operators);
+ fprintf(file, "dot_as_separator=%i\n", evalops.parse_options.dot_as_separator);
+ fprintf(file, "use_custom_result_font=%i\n", use_custom_result_font);
+ fprintf(file, "use_custom_expression_font=%i\n", use_custom_expression_font);
+ fprintf(file, "use_custom_status_font=%i\n", use_custom_status_font);
+ fprintf(file, "custom_result_font=%s\n", custom_result_font.ascii());
+ fprintf(file, "custom_expression_font=%s\n", custom_expression_font.ascii());
+ fprintf(file, "custom_status_font=%s\n", custom_status_font.ascii());
+ if(status_error_color != QColor("red")) fprintf(file, "status_error_color=%s\n", status_error_color.name().ascii());
+ if(status_warning_color != QColor("blue")) fprintf(file, "status_warning_color=%s\n", status_warning_color.name().ascii());
+ fprintf(file, "multiplication_sign=%i\n", printops.multiplication_sign);
+ fprintf(file, "division_sign=%i\n", printops.division_sign);
+ for (QStringList::Iterator it = ((QalculateExpressionEdit*) expressionWidget)->expression_history.begin(); it != ((QalculateExpressionEdit*) expressionWidget)->expression_history.end(); ++it) {
+ fprintf(file, "expression_history=%s\n", (*it).ascii());
+ }
+ int lines = 50;
+ bool end_after_result = false;
+ bool doend = false;
+ for(QValueVector<QString>::size_type i = 0; i < inhistory.size() && !doend; i++) {
+ switch(inhistory_type[i]) {
+ case QALCULATE_HISTORY_EXPRESSION: {
+ fprintf(file, "history_expression=");
+ break;
+ }
+ case QALCULATE_HISTORY_TRANSFORMATION: {
+ fprintf(file, "history_transformation=");
+ break;
+ }
+ case QALCULATE_HISTORY_RESULT: {
+ fprintf(file, "history_result=");
+ lines--;
+ if(end_after_result) doend = true;
+ break;
+ }
+ case QALCULATE_HISTORY_RESULT_APPROXIMATE: {
+ fprintf(file, "history_result_approximate=");
+ lines--;
+ if(end_after_result) doend = true;
+ break;
+ }
+ case QALCULATE_HISTORY_PARSE: {
+ fprintf(file, "history_parse=");
+ lines--;
+ if(lines < 0) end_after_result = true;
+ break;
+ }
+ case QALCULATE_HISTORY_PARSE_APPROXIMATE: {
+ fprintf(file, "history_parse_approximate=");
+ lines--;
+ if(lines < 0) end_after_result = true;
+ break;
+ }
+ case QALCULATE_HISTORY_REGISTER_MOVED: {
+ fprintf(file, "history_register_moved=");
+ break;
+ }
+ case QALCULATE_HISTORY_WARNING: {
+ fprintf(file, "history_warning=");
+ lines--;
+ break;
+ }
+ case QALCULATE_HISTORY_ERROR: {
+ fprintf(file, "history_error=");
+ lines--;
+ break;
+ }
+ case QALCULATE_HISTORY_OLD: {
+ fprintf(file, "history_old=");
+ lines--;
+ if(lines < 0) doend = true;
+ break;
+ }
+ }
+ if(inhistory[i].find("<br>") < 0) {
+ fprintf(file, "%s\n", inhistory[i].ascii());
+ } else {
+ QStringList slist = QStringList::split("<br>", inhistory[i], true);
+ for(QStringList::size_type i2 = 0; i2 < slist.size(); i2++) {
+ if(i2 == 0) fprintf(file, "%s\n", slist[i2].ascii());
+ else fprintf(file, "history_continued=%s\n", slist[i2].ascii());
+ }
+ }
+ }
+ fprintf(file, "recent_functions=");
+ for(int i = (int) (recent_functions.size()) - 1; i >= 0; i--) {
+ fprintf(file, "%s", recent_functions[i]->referenceName().c_str());
+ if(i != 0) fprintf(file, ",");
+ }
+ fprintf(file, "\n");
+ fprintf(file, "recent_variables=");
+ for(int i = (int) (recent_variables.size()) - 1; i >= 0; i--) {
+ fprintf(file, "%s", recent_variables[i]->referenceName().c_str());
+ if(i != 0) fprintf(file, ",");
+ }
+ fprintf(file, "\n");
+ fprintf(file, "recent_units=");
+ for(int i = (int) (recent_units.size()) - 1; i >= 0; i--) {
+ fprintf(file, "%s", recent_units[i]->referenceName().c_str());
+ if(i != 0) fprintf(file, ",");
+ }
+ fprintf(file, "\n");
+ if(mode)
+ set_saved_mode();
+ for(size_t i = 1; i < modes.size(); i++) {
+ if(i == 1) {
+ fprintf(file, "\n[Mode]\n");
+ } else {
+ fprintf(file, "\n[Mode %s]\n", modes[i].name.ascii());
+ if(!modes[i].shortcut.toString().isNull()) fprintf(file, "shortcut=%s\n", modes[i].shortcut.toString().ascii());
+ }
+ fprintf(file, "min_deci=%i\n", modes[i].po.min_decimals);
+ fprintf(file, "use_min_deci=%i\n", modes[i].po.use_min_decimals);
+ fprintf(file, "max_deci=%i\n", modes[i].po.max_decimals);
+ fprintf(file, "use_max_deci=%i\n", modes[i].po.use_max_decimals);
+ fprintf(file, "precision=%i\n", modes[i].precision);
+ fprintf(file, "min_exp=%i\n", modes[i].po.min_exp);
+ fprintf(file, "negative_exponents=%i\n", modes[i].po.negative_exponents);
+ fprintf(file, "sort_minus_last=%i\n", modes[i].po.sort_options.minus_last);
+ fprintf(file, "number_fraction_format=%i\n", modes[i].po.number_fraction_format);
+ fprintf(file, "use_prefixes=%i\n", modes[i].po.use_unit_prefixes);
+ fprintf(file, "abbreviate_names=%i\n", modes[i].po.abbreviate_names);
+ fprintf(file, "all_prefixes_enabled=%i\n", modes[i].po.use_all_prefixes);
+ fprintf(file, "denominator_prefix_enabled=%i\n", modes[i].po.use_denominator_prefix);
+ fprintf(file, "place_units_separately=%i\n", modes[i].po.place_units_separately);
+ fprintf(file, "auto_post_conversion=%i\n", modes[i].eo.auto_post_conversion);
+ fprintf(file, "number_base=%i\n", modes[i].po.base);
+ fprintf(file, "number_base_expression=%i\n", modes[i].eo.parse_options.base);
+ fprintf(file, "read_precision=%i\n", modes[i].eo.parse_options.read_precision);
+ fprintf(file, "assume_denominators_nonzero=%i\n", modes[i].eo.assume_denominators_nonzero);
+ fprintf(file, "warn_about_denominators_assumed_nonzero=%i\n", modes[i].eo.warn_about_denominators_assumed_nonzero);
+ fprintf(file, "structuring=%i\n", modes[i].eo.structuring);
+ fprintf(file, "angle_unit=%i\n", modes[i].eo.parse_options.angle_unit);
+ fprintf(file, "functions_enabled=%i\n", modes[i].eo.parse_options.functions_enabled);
+ fprintf(file, "variables_enabled=%i\n", modes[i].eo.parse_options.variables_enabled);
+ fprintf(file, "calculate_functions=%i\n", modes[i].eo.calculate_functions);
+ fprintf(file, "calculate_variables=%i\n", modes[i].eo.calculate_variables);
+ fprintf(file, "sync_units=%i\n", modes[i].eo.sync_units);
+ fprintf(file, "unknownvariables_enabled=%i\n", modes[i].eo.parse_options.unknowns_enabled);
+ fprintf(file, "units_enabled=%i\n", modes[i].eo.parse_options.units_enabled);
+ fprintf(file, "allow_complex=%i\n", modes[i].eo.allow_complex);
+ fprintf(file, "allow_infinite=%i\n", modes[i].eo.allow_infinite);
+ fprintf(file, "indicate_infinite_series=%i\n", modes[i].po.indicate_infinite_series);
+ fprintf(file, "show_ending_zeroes=%i\n", modes[i].po.show_ending_zeroes);
+ fprintf(file, "round_halfway_to_even=%i\n", modes[i].po.round_halfway_to_even);
+ fprintf(file, "approximation=%i\n", modes[i].eo.approximation);
+ fprintf(file, "in_rpn_mode=%i\n", modes[i].rpn_mode);
+ fprintf(file, "rpn_syntax=%i\n", modes[i].eo.parse_options.rpn);
+ fprintf(file, "limit_implicit_multiplication=%i\n", modes[i].eo.parse_options.limit_implicit_multiplication);
+ fprintf(file, "spacious=%i\n", modes[i].po.spacious);
+ fprintf(file, "excessive_parenthesis=%i\n", modes[i].po.excessive_parenthesis);
+ fprintf(file, "short_multiplication=%i\n", modes[i].po.short_multiplication);
+ fprintf(file, "default_assumption_type=%i\n", modes[i].at);
+ fprintf(file, "default_assumption_sign=%i\n", modes[i].as);
+ }
+
+ fprintf(file, "\n[Plotting]\n");
+ fprintf(file, "plot_legend_placement=%i\n", default_plot_legend_placement);
+ fprintf(file, "plot_style=%i\n", default_plot_style);
+ fprintf(file, "plot_smoothing=%i\n", default_plot_smoothing);
+ fprintf(file, "plot_display_grid=%i\n", default_plot_display_grid);
+ fprintf(file, "plot_full_border=%i\n", default_plot_full_border);
+ fprintf(file, "plot_min=%s\n", default_plot_min.ascii());
+ fprintf(file, "plot_max=%s\n", default_plot_max.ascii());
+ fprintf(file, "plot_step=%s\n", default_plot_step.ascii());
+ fprintf(file, "plot_sampling_rate=%i\n", default_plot_sampling_rate);
+ fprintf(file, "plot_use_sampling_rate=%i\n", default_plot_use_sampling_rate);
+ fprintf(file, "plot_variable=%s\n", default_plot_variable.ascii());
+ fprintf(file, "plot_rows=%i\n", default_plot_rows);
+ fprintf(file, "plot_type=%i\n", default_plot_type);
+ fprintf(file, "plot_color=%i\n", default_plot_color);
+ fprintf(file, "enable_plot_expression_completion=%i\n", enable_plot_expression_completion);
+
+
+ fclose(file);
+
+}
diff --git a/src/preferences.h b/src/preferences.h
new file mode 100644
index 0000000..9547989
--- /dev/null
+++ b/src/preferences.h
@@ -0,0 +1,42 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef PREFERENCES_H
+#define PREFERENCES_H
+
+enum {
+ QALCULATE_HISTORY_EXPRESSION,
+ QALCULATE_HISTORY_TRANSFORMATION,
+ QALCULATE_HISTORY_RESULT,
+ QALCULATE_HISTORY_RESULT_APPROXIMATE,
+ QALCULATE_HISTORY_PARSE,
+ QALCULATE_HISTORY_PARSE_APPROXIMATE,
+ QALCULATE_HISTORY_WARNING,
+ QALCULATE_HISTORY_ERROR,
+ QALCULATE_HISTORY_OLD,
+ QALCULATE_HISTORY_REGISTER_MOVED
+};
+
+void save_mode();
+
+void load_preferences();
+void save_preferences(bool mode = false);
+
+#endif
diff --git a/src/qalculate_kde.desktop b/src/qalculate_kde.desktop
new file mode 100644
index 0000000..c01c30b
--- /dev/null
+++ b/src/qalculate_kde.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Name=Qalculate!
+GenericName=Scientific Calculator
+Exec=qalculate-kde
+Icon=qalculate_kde
+Type=Application
+DocPath=qalculate_kde/index.html
+Categories=Qt;KDE;Utility;Science;
+Terminal=false
+X-DCOP-ServiceType=Unique
+X-DCOP-ServiceName=qalculate_kde
+X-KDE-StartupNotify=true
+Comment=Powerful and easy to use desktop calculator
diff --git a/src/qalculate_kde_utils.cpp b/src/qalculate_kde_utils.cpp
new file mode 100644
index 0000000..5bcb8c5
--- /dev/null
+++ b/src/qalculate_kde_utils.cpp
@@ -0,0 +1,307 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#include "qalculate_kde_utils.h"
+#include <qwidget.h>
+#include <qlabel.h>
+#include <qlineedit.h>
+#include <qstring.h>
+#include <qfont.h>
+#include <qfontmetrics.h>
+#include "kqalculate.h"
+
+tree_struct function_cats, unit_cats, variable_cats;
+vector<void*> ia_units, ia_variables, ia_functions;
+vector<MathFunction*> recent_functions;
+vector<Variable*> recent_variables;
+vector<Unit*> recent_units;
+extern PrintOptions printops;
+extern KnownVariable *vans[5];
+extern QWidget *topWidget;
+extern KQalculate *mainWin;
+
+void insert_text_in_expression(const QString &str) {
+ mainWin->insert_text(str);
+}
+
+bool is_answer_variable(Variable *v) {
+ return v == vans[0] || v == vans[1] || v == vans[2] || v == vans[3] || v == vans[4];
+}
+
+QString get_value_string(const MathStructure &mstruct_, bool rlabel, Prefix *prefix) {
+ printops.allow_non_usable = rlabel;
+ printops.prefix = prefix;
+ QString str = CALCULATOR->printMathStructureTimeOut(mstruct_, 100, printops).c_str();
+ printops.allow_non_usable = false;
+ printops.prefix = NULL;
+ return str;
+}
+
+void set_name_label_and_entry(ExpressionItem *item, QLineEdit *entry, QLabel *label) {
+ const ExpressionName *ename = &item->getName(1);
+ entry->setText(ename->name.c_str());
+ if(item->countNames() > 1) {
+ QString str = "+ ";
+ for(size_t i = 2; i <= item->countNames(); i++) {
+ if(i > 2) str += ", ";
+ str += item->getName(i).name.c_str();
+ }
+ label->setText(str);
+ }
+}
+
+bool can_display_unicode_string_function(const char *str, void *arg) {
+ if(!arg) arg = (void*) topWidget;
+ QFontMetrics fm(((QWidget*) arg)->fontMetrics());
+ QString qstr(str);
+ const QChar *qchars = qstr.unicode();
+ for(uint i = 0; i < qstr.length(); i++) {
+ if(!fm.inFont(qchars[i])) return false;
+ }
+ return true;
+}
+
+void generate_units_tree_struct() {
+ size_t cat_i, cat_i_prev;
+ bool b;
+ string str, cat, cat_sub;
+ Unit *u = NULL;
+ unit_cats.items.clear();
+ unit_cats.objects.clear();
+ unit_cats.parent = NULL;
+ ia_units.clear();
+ list<tree_struct>::iterator it;
+ for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
+ if(!CALCULATOR->units[i]->isActive()) {
+ b = false;
+ for(size_t i3 = 0; i3 < ia_units.size(); i3++) {
+ u = (Unit*) ia_units[i3];
+ if(CALCULATOR->units[i]->title() < u->title()) {
+ b = true;
+ ia_units.insert(ia_units.begin() + i3, (void*) CALCULATOR->units[i]);
+ break;
+ }
+ }
+ if(!b) ia_units.push_back((void*) CALCULATOR->units[i]);
+ } else {
+ tree_struct *item = &unit_cats;
+ if(!CALCULATOR->units[i]->category().empty()) {
+ cat = CALCULATOR->units[i]->category();
+ cat_i = cat.find("/"); cat_i_prev = 0;
+ b = false;
+ while(true) {
+ if(cat_i == string::npos) {
+ cat_sub = cat.substr(cat_i_prev, cat.length() - cat_i_prev);
+ } else {
+ cat_sub = cat.substr(cat_i_prev, cat_i - cat_i_prev);
+ }
+ b = false;
+ for(it = item->items.begin(); it != item->items.end(); ++it) {
+ if(cat_sub == it->item) {
+ item = &*it;
+ b = true;
+ break;
+ }
+ }
+ if(!b) {
+ tree_struct cat;
+ item->items.push_back(cat);
+ it = item->items.end();
+ --it;
+ it->parent = item;
+ item = &*it;
+ item->item = cat_sub;
+ }
+ if(cat_i == string::npos) {
+ break;
+ }
+ cat_i_prev = cat_i + 1;
+ cat_i = cat.find("/", cat_i_prev);
+ }
+ }
+ b = false;
+ for(size_t i3 = 0; i3 < item->objects.size(); i3++) {
+ u = (Unit*) item->objects[i3];
+ if(CALCULATOR->units[i]->title() < u->title()) {
+ b = true;
+ item->objects.insert(item->objects.begin() + i3, (void*) CALCULATOR->units[i]);
+ break;
+ }
+ }
+ if(!b) item->objects.push_back((void*) CALCULATOR->units[i]);
+ }
+ }
+
+ unit_cats.sort();
+
+}
+void generate_variables_tree_struct() {
+
+ size_t cat_i, cat_i_prev;
+ bool b;
+ string str, cat, cat_sub;
+ Variable *v = NULL;
+ variable_cats.items.clear();
+ variable_cats.objects.clear();
+ variable_cats.parent = NULL;
+ ia_variables.clear();
+ list<tree_struct>::iterator it;
+ for(size_t i = 0; i < CALCULATOR->variables.size(); i++) {
+ if(!CALCULATOR->variables[i]->isActive()) {
+ //deactivated variable
+ b = false;
+ for(size_t i3 = 0; i3 < ia_variables.size(); i3++) {
+ v = (Variable*) ia_variables[i3];
+ if(CALCULATOR->variables[i]->title() < v->title()) {
+ b = true;
+ ia_variables.insert(ia_variables.begin() + i3, (void*) CALCULATOR->variables[i]);
+ break;
+ }
+ }
+ if(!b) ia_variables.push_back((void*) CALCULATOR->variables[i]);
+ } else {
+ tree_struct *item = &variable_cats;
+ if(!CALCULATOR->variables[i]->category().empty()) {
+ cat = CALCULATOR->variables[i]->category();
+ cat_i = cat.find("/"); cat_i_prev = 0;
+ b = false;
+ while(true) {
+ if(cat_i == string::npos) {
+ cat_sub = cat.substr(cat_i_prev, cat.length() - cat_i_prev);
+ } else {
+ cat_sub = cat.substr(cat_i_prev, cat_i - cat_i_prev);
+ }
+ b = false;
+ for(it = item->items.begin(); it != item->items.end(); ++it) {
+ if(cat_sub == it->item) {
+ item = &*it;
+ b = true;
+ break;
+ }
+ }
+ if(!b) {
+ tree_struct cat;
+ item->items.push_back(cat);
+ it = item->items.end();
+ --it;
+ it->parent = item;
+ item = &*it;
+ item->item = cat_sub;
+ }
+ if(cat_i == string::npos) {
+ break;
+ }
+ cat_i_prev = cat_i + 1;
+ cat_i = cat.find("/", cat_i_prev);
+ }
+ }
+ b = false;
+ for(size_t i3 = 0; i3 < item->objects.size(); i3++) {
+ v = (Variable*) item->objects[i3];
+ if(CALCULATOR->variables[i]->title() < v->title()) {
+ b = true;
+ item->objects.insert(item->objects.begin() + i3, (void*) CALCULATOR->variables[i]);
+ break;
+ }
+ }
+ if(!b) item->objects.push_back((void*) CALCULATOR->variables[i]);
+ }
+ }
+
+ variable_cats.sort();
+
+}
+void generate_functions_tree_struct() {
+
+ size_t cat_i, cat_i_prev;
+ bool b;
+ string str, cat, cat_sub;
+ MathFunction *f = NULL;
+ function_cats.items.clear();
+ function_cats.objects.clear();
+ function_cats.parent = NULL;
+ ia_functions.clear();
+ list<tree_struct>::iterator it;
+
+ for(size_t i = 0; i < CALCULATOR->functions.size(); i++) {
+ if(!CALCULATOR->functions[i]->isActive()) {
+ //deactivated function
+ b = false;
+ for(size_t i3 = 0; i3 < ia_functions.size(); i3++) {
+ f = (MathFunction*) ia_functions[i3];
+ if(CALCULATOR->functions[i]->title() < f->title()) {
+ b = true;
+ ia_functions.insert(ia_functions.begin() + i3, (void*) CALCULATOR->functions[i]);
+ break;
+ }
+ }
+ if(!b) ia_functions.push_back((void*) CALCULATOR->functions[i]);
+ } else {
+ tree_struct *item = &function_cats;
+ if(!CALCULATOR->functions[i]->category().empty()) {
+ cat = CALCULATOR->functions[i]->category();
+ cat_i = cat.find("/"); cat_i_prev = 0;
+ b = false;
+ while(true) {
+ if(cat_i == string::npos) {
+ cat_sub = cat.substr(cat_i_prev, cat.length() - cat_i_prev);
+ } else {
+ cat_sub = cat.substr(cat_i_prev, cat_i - cat_i_prev);
+ }
+ b = false;
+ for(it = item->items.begin(); it != item->items.end(); ++it) {
+ if(cat_sub == it->item) {
+ item = &*it;
+ b = true;
+ break;
+ }
+ }
+ if(!b) {
+ tree_struct cat;
+ item->items.push_back(cat);
+ it = item->items.end();
+ --it;
+ it->parent = item;
+ item = &*it;
+ item->item = cat_sub;
+ }
+ if(cat_i == string::npos) {
+ break;
+ }
+ cat_i_prev = cat_i + 1;
+ cat_i = cat.find("/", cat_i_prev);
+ }
+ }
+ b = false;
+ for(size_t i3 = 0; i3 < item->objects.size(); i3++) {
+ f = (MathFunction*) item->objects[i3];
+ if(CALCULATOR->functions[i]->title() < f->title()) {
+ b = true;
+ item->objects.insert(item->objects.begin() + i3, (void*) CALCULATOR->functions[i]);
+ break;
+ }
+ }
+ if(!b) item->objects.push_back((void*) CALCULATOR->functions[i]);
+ }
+ }
+
+ function_cats.sort();
+
+}
diff --git a/src/qalculate_kde_utils.h b/src/qalculate_kde_utils.h
new file mode 100644
index 0000000..2632739
--- /dev/null
+++ b/src/qalculate_kde_utils.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifndef QALCULATE_KDE_UTILS_H
+#define QALCULATE_KDE_UTILS_H
+
+#include <libqalculate/qalculate.h>
+#undef insertItem
+#undef addItem
+#undef setItem
+#undef getItem
+
+#include <qstring.h>
+#include <kshortcut.h>
+
+class QLabel;
+class QLineEdit;
+
+struct tree_struct {
+ string item;
+ list<tree_struct> items;
+ list<tree_struct>::iterator it;
+ list<tree_struct>::reverse_iterator rit;
+ vector<void*> objects;
+ tree_struct *parent;
+ void sort() {
+ items.sort();
+ for(list<tree_struct>::iterator it = items.begin(); it != items.end(); ++it) {
+ it->sort();
+ }
+ }
+ bool operator < (tree_struct &s1) const {
+ return item < s1.item;
+ }
+};
+struct mode_struct {
+ PrintOptions po;
+ EvaluationOptions eo;
+ AssumptionType at;
+ AssumptionSign as;
+ int precision;
+ QString name;
+ bool rpn_mode;
+ KShortcut shortcut;
+};
+
+void insert_text_in_expression(const QString &str);
+bool is_answer_variable(Variable *v);
+QString get_value_string(const MathStructure &mstruct_, bool rlabel = false, Prefix *prefix = NULL);
+void set_name_label_and_entry(ExpressionItem *item, QLineEdit *entry, QLabel *label);
+bool can_display_unicode_string_function(const char *str, void *arg);
+void generate_units_tree_struct();
+void generate_functions_tree_struct();
+void generate_variables_tree_struct();
+size_t save_mode_as(QString name, bool *new_mode = NULL);
+
+#endif
diff --git a/src/qalculate_kdeui.rc b/src/qalculate_kdeui.rc
new file mode 100644
index 0000000..eae44d9
--- /dev/null
+++ b/src/qalculate_kdeui.rc
@@ -0,0 +1,168 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="kqalculate">
+ <MenuBar>
+ <Menu name="file"><text>&amp;File</text>
+ <Menu name="new" icon="filenew"><text>&amp;New</text>
+ <Action name="new_variable"/>
+ <Action name="new_matrix"/>
+ <Action name="new_vector"/>
+ <Action name="new_unknown_variable"/>
+ <Action name="new_function"/>
+ <Action name="new_data_set"/>
+ <Action name="new_unit"/>
+ </Menu>
+ <Action name="import_csv_file"/>
+ <Action name="export_csv_file"/>
+ <Action name="store_result"/>
+ <Action name="save_as_image"/>
+ <Separator/>
+ <Action name="save_definitions"/>
+ <Action name="update_exchange_rates"/>
+ <Separator/>
+ <Action name="plot_functions_data"/>
+ <Action name="convert_number_bases"/>
+ <Action name="periodic_table"/>
+ <Separator/>
+ <Action name="quit"/>
+ </Menu>
+ <Menu name="edit"><text>&amp;Edit</text>
+ <Action name="manage_variables"/>
+ <Action name="manage_functions"/>
+ <Action name="manage_units"/>
+ <Action name="manage_data_sets"/>
+ <Separator/>
+ <Action name="factorize"/>
+ <Action name="simplify"/>
+ <Action name="set_unknowns"/>
+ <Menu name="set_prefix"><text>&amp;Set Prefix</text>
+ </Menu>
+ <Menu name="convert_to_unit"><text>&amp;Convert To Unit</text>
+ </Menu>
+ <Action name="convert_to_unit_expression"/>
+ <Action name="convert_to_base_units"/>
+ <Action name="convert_to_best_unit"/>
+ <Separator/>
+ <Action name="insert_matrix"/>
+ <Action name="insert_vector"/>
+ <Separator/>
+ <Action name="copy_result"/>
+ <Separator/>
+ <Action name="preferences"/>
+ <Action name="keybindings"/>
+ <Action name="configure_global_shortcuts"/>
+ </Menu>
+ <Menu name="mode"><text>&amp;Mode</text>
+ <Menu name="number_base"><text>Number Base</text>
+ <Action name="set_base"/>
+ <Separator/>
+ <Action name="number_base_binary"/>
+ <Action name="number_base_octal"/>
+ <Action name="number_base_decimal"/>
+ <Action name="number_base_hexadecimal"/>
+ <Action name="number_base_sexagesimal"/>
+ <Action name="number_base_time_format"/>
+ <Action name="number_base_roman_numerals"/>
+ <Action name="number_base_other"/>
+ </Menu>
+ <Menu name="numerical_display"><text>Numerical Display</text>
+ <Action name="numerical_display_normal"/>
+ <Action name="numerical_display_engineering"/>
+ <Action name="numerical_display_scientific"/>
+ <Action name="numerical_display_purely_scientific"/>
+ <Action name="numerical_display_simple"/>
+ <Separator/>
+ <Action name="indicate_infinite_series"/>
+ <Action name="show_ending_zeroes"/>
+ <Action name="round_halfway_numbers_to_even"/>
+ <Action name="negative_exponents"/>
+ <Action name="sort_minus_last"/>
+ </Menu>
+ <Menu name="fractional_display"><text>Fractional Display</text>
+ <Action name="fractional_display_decimal"/>
+ <Action name="fractional_display_decimal_try_exact"/>
+ <Action name="fractional_display_fraction"/>
+ <Action name="fractional_display_combined"/>
+ </Menu>
+ <Menu name="unit_display"><text>Unit Display</text>
+ <Action name="enable_prefixes"/>
+ <Action name="enable_use_of_all_prefixes"/>
+ <Action name="enable_denominator_prefixes"/>
+ <Action name="place_units_separately"/>
+ <Separator/>
+ <Action name="auto_no_conversion"/>
+ <Action name="auto_convert_to_base_units"/>
+ <Action name="auto_convert_to_best_unit"/>
+ </Menu>
+ <Menu name="angle_unit"><text>Angle Unit</text>
+ <Action name="angle_unit_degrees"/>
+ <Action name="angle_unit_radians"/>
+ <Action name="angle_unit_gradians"/>
+ <Action name="angle_unit_none"/>
+ </Menu>
+ <Action name="abbreviate_names"/>
+ <Separator/>
+ <Menu name="enabled_objects"><text>Enabled Objects</text>
+ <Action name="enable_variables"/>
+ <Action name="enable_functions"/>
+ <Action name="enable_units"/>
+ <Action name="enable_unknowns"/>
+ <Separator/>
+ <Action name="calculate_variables"/>
+ <Separator/>
+ <Action name="allow_complex_result"/>
+ <Action name="allow_infinite_result"/>
+ </Menu>
+ <Separator/>
+ <Menu name="approximation"><text>Approximation</text>
+ <Action name="approximation_try_exact"/>
+ <Action name="approximation_always_exact"/>
+ <Action name="approximation_approximate"/>
+ </Menu>
+ <Menu name="assumptions"><text>Assumptions</text>
+ <Action name="assumption_type_unknown"/>
+ <Action name="assumption_type_nonmatrix"/>
+ <Action name="assumption_type_number"/>
+ <Action name="assumption_type_complex"/>
+ <Action name="assumption_type_real"/>
+ <Action name="assumption_type_rational"/>
+ <Action name="assumption_type_integer"/>
+ <Separator/>
+ <Action name="assumption_sign_unknown"/>
+ <Action name="assumption_sign_non_zero"/>
+ <Action name="assumption_sign_positive"/>
+ <Action name="assumption_sign_non_negative"/>
+ <Action name="assumption_sign_negative"/>
+ <Action name="assumption_sign_non_positive"/>
+ </Menu>
+ <Menu name="algebraic_mode"><text>Algebraic Mode</text>
+ <Action name="algebraic_mode_simplify"/>
+ <Action name="algebraic_mode_factorize"/>
+ <Action name="algebraic_mode_none"/>
+ <Separator/>
+ <Action name="non_zero_denominators"/>
+ <Action name="warn_about_denominators_assumed_nonzero"/>
+ </Menu>
+ <Separator/>
+ <Action name="read_precision"/>
+ <Action name="limit_implicit_multiplication"/>
+ <Action name="rpn_mode"/>
+ <Action name="rpn_syntax"/>
+ <Separator/>
+ <Action name="precision"/>
+ <Action name="decimals"/>
+ <Separator/>
+ <Menu name="modes"><text>Meta Modes</text>
+ <Separator/>
+ <Action name="save_mode_as"/>
+ <Action name="delete_mode"/>
+ </Menu>
+ <Action name="save_mode"/>
+ </Menu>
+ <Menu name="functions"><text>Fu&amp;nctions</text>
+ </Menu>
+ <Menu name="variables"><text>&amp;Variables</text>
+ </Menu>
+ <Menu name="units"><text>&amp;Units</text>
+ </Menu>
+ </MenuBar>
+</kpartgui> \ No newline at end of file
diff --git a/src/qalculatebuttonwithdata.cpp b/src/qalculatebuttonwithdata.cpp
new file mode 100644
index 0000000..0b4ced7
--- /dev/null
+++ b/src/qalculatebuttonwithdata.cpp
@@ -0,0 +1,37 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculatebuttonwithdata.h"
+
+QalculateButtonWithData::QalculateButtonWithData(void *data, const QString & text, QWidget *parent, const char *name) : QPushButton(text, parent, name) {
+ user_data = data;
+ QObject::connect(this, SIGNAL(clicked()), this, SLOT(emitClickedWithData()));
+}
+QalculateButtonWithData::QalculateButtonWithData(void *data, const QIconSet & icon, const QString & text, QWidget * parent, const char * name) : QPushButton(icon, text, parent, name) {
+ user_data = data;
+ QObject::connect(this, SIGNAL(clicked()), this, SLOT(emitClickedWithData()));
+}
+QalculateButtonWithData::~QalculateButtonWithData() {}
+void QalculateButtonWithData::emitClickedWithData() {
+ emit clickedWithData(user_data);
+}
+
+
+
+#include "qalculatebuttonwithdata.moc"
diff --git a/src/qalculatebuttonwithdata.h b/src/qalculatebuttonwithdata.h
new file mode 100644
index 0000000..b3281a3
--- /dev/null
+++ b/src/qalculatebuttonwithdata.h
@@ -0,0 +1,48 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEBUTTONWITHDATA_H
+#define QALCULATEBUTTONWITHDATA_H
+
+#include <qpushbutton.h>
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateButtonWithData : public QPushButton {
+ Q_OBJECT
+
+public:
+
+ QalculateButtonWithData(void *data, const QString & text, QWidget *parent, const char *name = 0);
+ QalculateButtonWithData(void *data, const QIconSet & icon, const QString & text, QWidget * parent, const char * name = 0);
+ virtual ~QalculateButtonWithData();
+ void *user_data;
+
+protected slots:
+
+ void emitClickedWithData();
+
+signals:
+
+ void clickedWithData(void*);
+
+};
+
+#endif
diff --git a/src/qalculateconvertnumberbasesdialog.cpp b/src/qalculateconvertnumberbasesdialog.cpp
new file mode 100644
index 0000000..79585c1
--- /dev/null
+++ b/src/qalculateconvertnumberbasesdialog.cpp
@@ -0,0 +1,122 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateconvertnumberbasesdialog.h"
+#include "qalculate_kde_utils.h"
+#include <klocale.h>
+#include <qgrid.h>
+#include <qlabel.h>
+#include <klineedit.h>
+#include <qpushbutton.h>
+
+extern EvaluationOptions evalops;
+
+QalculateConvertNumberBasesDialog::QalculateConvertNumberBasesDialog(QWidget *parent, const char *name)
+ : KDialogBase(parent, name, false, i18n("Number Bases"), Close, Close) {
+
+ actionButton(Close)->setAutoDefault(false);
+ actionButton(Close)->setDefault(false);
+
+ QGrid *grid = makeGridMainWidget(2, Qt::Horizontal);
+ new QLabel(i18n("Decimal:"), grid);
+ decimalEdit = new KLineEdit(grid);
+ decimalEdit->setAlignment(Qt::AlignRight);
+ QObject::connect(decimalEdit, SIGNAL(textChanged(const QString&)), this, SLOT(setDecimalValue(const QString&)));
+ new QLabel(i18n("Binary:"), grid);
+ binaryEdit = new KLineEdit(grid);
+ binaryEdit->setAlignment(Qt::AlignRight);
+ QObject::connect(binaryEdit, SIGNAL(textChanged(const QString&)), this, SLOT(setBinaryValue(const QString&)));
+ new QLabel(i18n("Octal:"), grid);
+ octalEdit = new KLineEdit(grid);
+ octalEdit->setAlignment(Qt::AlignRight);
+ QObject::connect(octalEdit, SIGNAL(textChanged(const QString&)), this, SLOT(setOctalValue(const QString&)));
+ new QLabel(i18n("Hexadecimal:"), grid);
+ hexadecimalEdit = new KLineEdit(grid);
+ hexadecimalEdit->setAlignment(Qt::AlignRight);
+ QObject::connect(hexadecimalEdit, SIGNAL(textChanged(const QString&)), this, SLOT(setHexadecimalValue(const QString&)));
+
+ decimalEdit->setFocus();
+
+}
+
+
+QalculateConvertNumberBasesDialog::~QalculateConvertNumberBasesDialog() {}
+
+void QalculateConvertNumberBasesDialog::setDecimalValue(const QString &qstr) {
+ string str = qstr.ascii();
+ remove_blank_ends(str);
+ if(str.empty()) return;
+ if(is_in(OPERATORS EXP, str[str.length() - 1])) return;
+ EvaluationOptions eo;
+ eo.parse_options.angle_unit = evalops.parse_options.angle_unit;
+ MathStructure value = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo);
+ updateEntries(&value, 10);
+}
+void QalculateConvertNumberBasesDialog::setBinaryValue(const QString &qstr) {
+ string str = qstr.ascii();
+ remove_blank_ends(str);
+ if(str.empty()) return;
+ if(is_in(OPERATORS EXP, str[str.length() - 1])) return;
+ EvaluationOptions eo;
+ eo.parse_options.base = BASE_BINARY;
+ eo.parse_options.angle_unit = evalops.parse_options.angle_unit;
+ MathStructure value = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo);
+ updateEntries(&value, 2);
+}
+void QalculateConvertNumberBasesDialog::setOctalValue(const QString &qstr) {
+ string str = qstr.ascii();
+ remove_blank_ends(str);
+ if(str.empty()) return;
+ if(is_in(OPERATORS EXP, str[str.length() - 1])) return;
+ EvaluationOptions eo;
+ eo.parse_options.base = BASE_OCTAL;
+ eo.parse_options.angle_unit = evalops.parse_options.angle_unit;
+ MathStructure value = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo);
+ updateEntries(&value, 8);
+}
+void QalculateConvertNumberBasesDialog::setHexadecimalValue(const QString &qstr) {
+ string str = qstr.ascii();
+ remove_blank_ends(str);
+ if(str.empty()) return;
+ if(is_in(OPERATORS EXP, str[str.length() - 1])) return;
+ EvaluationOptions eo;
+ eo.parse_options.angle_unit = evalops.parse_options.angle_unit;
+ eo.parse_options.base = BASE_HEXADECIMAL;
+ MathStructure value = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo);
+ updateEntries(&value, 16);
+}
+
+void QalculateConvertNumberBasesDialog::updateEntries(const MathStructure *value, int base) {
+ decimalEdit->blockSignals(true);
+ binaryEdit->blockSignals(true);
+ octalEdit->blockSignals(true);
+ hexadecimalEdit->blockSignals(true);
+ PrintOptions po;
+ po.number_fraction_format = FRACTION_DECIMAL;
+ if(base != 10) {po.base = 10; decimalEdit->setText(value->print(po).c_str());}
+ if(base != 2) {po.base = 2; binaryEdit->setText(value->print(po).c_str());}
+ if(base != 8) {po.base = 8; octalEdit->setText(value->print(po).c_str());}
+ if(base != 16) {po.base = 16; hexadecimalEdit->setText(value->print(po).c_str());}
+ decimalEdit->blockSignals(false);
+ binaryEdit->blockSignals(false);
+ octalEdit->blockSignals(false);
+ hexadecimalEdit->blockSignals(false);
+}
+
+#include "qalculateconvertnumberbasesdialog.moc"
diff --git a/src/qalculateconvertnumberbasesdialog.h b/src/qalculateconvertnumberbasesdialog.h
new file mode 100644
index 0000000..943fede
--- /dev/null
+++ b/src/qalculateconvertnumberbasesdialog.h
@@ -0,0 +1,53 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATECONVERTNUMBERBASESDIALOG_H
+#define QALCULATECONVERTNUMBERBASESDIALOG_H
+
+#include <kdialogbase.h>
+
+class KLineEdit;
+class MathStructure;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateConvertNumberBasesDialog : public KDialogBase {
+ Q_OBJECT
+public:
+ QalculateConvertNumberBasesDialog(QWidget *parent = 0, const char *name = 0);
+
+ virtual ~QalculateConvertNumberBasesDialog();
+
+ KLineEdit *binaryEdit, *octalEdit, *decimalEdit, *hexadecimalEdit;
+
+public slots:
+
+ void setDecimalValue(const QString&);
+ void setBinaryValue(const QString&);
+ void setOctalValue(const QString&);
+ void setHexadecimalValue(const QString&);
+
+protected:
+
+ void updateEntries(const MathStructure *value, int base);
+
+};
+
+#endif
diff --git a/src/qalculateconvertunitsdialog.cpp b/src/qalculateconvertunitsdialog.cpp
new file mode 100644
index 0000000..f3ebb61
--- /dev/null
+++ b/src/qalculateconvertunitsdialog.cpp
@@ -0,0 +1,205 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateconvertunitsdialog.h"
+#include "qalculate_kde_utils.h"
+
+#include <qlabel.h>
+#include <klineedit.h>
+#include <klocale.h>
+#include <qhbox.h>
+#include <klistview.h>
+#include <klocale.h>
+#include <qvbox.h>
+#include <klistview.h>
+#include <kmessagebox.h>
+#include <qlayout.h>
+#include <qpushbutton.h>
+#include <qsplitter.h>
+
+extern tree_struct unit_cats;
+extern vector<void*> ia_units;
+extern PrintOptions printops;
+extern EvaluationOptions evalops;
+
+
+QalculateConvertUnitsDialog::QalculateConvertUnitsDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Convert"), Ok | Apply | Cancel | Details, Ok, true) {
+
+ setButtonText(Details, i18n("Selector"));
+
+ selected_category = "";
+ block_unit_convert = true;
+
+ QVBox *box = makeVBoxMainWidget();
+ new QLabel(i18n("Unit expression:"), box);
+ unitExpressionEdit = new KLineEdit(box);
+
+ QVBox *box_d = new QVBox(this);
+ box_d->setSpacing(spacingHint());
+ new QWidget(box_d);
+
+ QSplitter *splitter = new QSplitter(Qt::Vertical, box_d);
+ splitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+
+ setDetailsWidget(box_d);
+
+ categoryView = new KListView(splitter);
+ categoryView->addColumn(i18n("Category"));
+ categoryView->setRootIsDecorated(false);
+ categoryView->setFullWidth(true);
+
+ unitView = new KListView(splitter);
+ unitView->addColumn(i18n("Unit"));
+ unitView->setRootIsDecorated(false);
+ unitView->setFullWidth(true);
+
+ unitExpressionEdit->setFocus();
+
+ connect(unitView, SIGNAL(selectionChanged()), this, SLOT(unitSelected()));
+ connect(categoryView, SIGNAL(selectionChanged()), this, SLOT(categorySelected()));
+
+}
+
+QalculateConvertUnitsDialog::~QalculateConvertUnitsDialog() {}
+
+void QalculateConvertUnitsDialog::updateUnitTree() {
+ unitItems.clear();
+ categoryItems.clear();
+ categoryView->clear();
+ QListViewItem *i = new KListViewItem(categoryView, i18n("All")), *i2;
+ categoryItems[i] = i18n("All");
+ i->setOpen(true);
+ QString str;
+ tree_struct *item, *item2;
+ unit_cats.it = unit_cats.items.begin();
+ if(unit_cats.it != unit_cats.items.end()) {
+ item = &*unit_cats.it;
+ ++unit_cats.it;
+ item->it = item->items.begin();
+ } else {
+ item = NULL;
+ }
+ str = "";
+ i2 = i;
+ while(item) {
+ str += "/";
+ str += item->item.c_str();
+ i = new KListViewItem(i2, item->item.c_str());
+ i->setOpen(false);
+ categoryItems[i] = str;
+ if(str == selected_category) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ while(item && item->it == item->items.end()) {
+ int str_i = str.findRev("/");
+ if(str_i < 0) {
+ str = "";
+ } else {
+ str.truncate(str_i);
+ }
+ item = item->parent;
+ i = i->parent();
+ i2 = i;
+ }
+ if(item) {
+ item2 = &*item->it;
+ if(item->it == item->items.begin())
+ i2 = i;
+ ++item->it;
+ item = item2;
+ item->it = item->items.begin();
+ }
+ }
+ if(!unit_cats.objects.empty()) {
+ //add "Uncategorized" category if there are units without category
+ i = new KListViewItem(categoryView, i18n("Uncategorized"));
+ categoryItems[i] = i18n("Uncategorized");
+ if(selected_category == i18n("Uncategorized")) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ }
+ if(!categoryView->selectedItem()) {
+ //if no category has been selected (previously selected has been renamed/deleted), select "All"
+ selected_category = i18n("All");
+ QListViewItemIterator it(categoryView);
+ if(it.current())
+ categoryView->setSelected(it.current(), true);
+ }
+}
+
+void QalculateConvertUnitsDialog::unitSelected() {
+ QListViewItem *selected = unitView->selectedItem();
+ if(selected) {
+ Unit *u = unitItems[selected];
+ if(!CALCULATOR->stillHasUnit(u)) {
+ KMessageBox::error(this, i18n("Unit does not exist anymore."));
+ emit unitsChanged();
+ return;
+ }
+ unitExpressionEdit->setText(u->print(false, printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) unitExpressionEdit).c_str());
+ unitView->selectAll(false);
+ if(!block_unit_convert) actionButton(Apply)->animateClick();
+ }
+}
+
+void QalculateConvertUnitsDialog::addUnitTreeItem(Unit *u) {
+ QListViewItem *i = new KListViewItem(unitView, u->title(true).c_str());
+ unitItems[i] = u;
+}
+
+
+void QalculateConvertUnitsDialog::categorySelected() {
+ block_unit_convert = true;
+ QListViewItem *selected = categoryView->selectedItem();
+ bool no_cat = false, b_all = false;
+ unitView->clear();
+ unitItems.clear();
+ if(!selected) {
+ selected_category = "";
+ return;
+ }
+ selected_category = categoryItems[selected];
+ if(selected_category == i18n("All")) {
+ b_all = true;
+ } else if(selected_category == i18n("Uncategorized")) {
+ no_cat = true;
+ }
+ if(!b_all && !no_cat && selected_category[0] == '/') {
+ string str = selected_category.ascii();
+ str.erase(str.begin());
+ for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
+ if(CALCULATOR->units[i]->isActive() && !CALCULATOR->units[i]->isHidden() && CALCULATOR->units[i]->category().substr(0, selected_category.length() - 1) == str) {
+ addUnitTreeItem(CALCULATOR->units[i]);
+ }
+ }
+ } else {
+ string str = selected_category.ascii();
+ for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
+ if(CALCULATOR->units[i]->isActive() && !CALCULATOR->units[i]->isHidden() && (b_all || (no_cat && CALCULATOR->units[i]->category().empty()) || CALCULATOR->units[i]->category() == str)) {
+ addUnitTreeItem(CALCULATOR->units[i]);
+ }
+ }
+ }
+ block_unit_convert = false;
+}
+
+
+#include "qalculateconvertunitsdialog.moc"
diff --git a/src/qalculateconvertunitsdialog.h b/src/qalculateconvertunitsdialog.h
new file mode 100644
index 0000000..7c6991c
--- /dev/null
+++ b/src/qalculateconvertunitsdialog.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATECONVERTUNITSDIALOG_H
+#define QALCULATECONVERTUNITSDIALOG_H
+
+#include <kdialogbase.h>
+#include <qmap.h>
+
+class KLineEdit;
+class Unit;
+class KListView;
+class QListViewItem;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateConvertUnitsDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateConvertUnitsDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateConvertUnitsDialog();
+
+ KLineEdit *unitExpressionEdit;
+
+ void addUnitTreeItem(Unit *f);
+ QMap<QListViewItem*, Unit*> unitItems;
+ QMap<QListViewItem*, QString> categoryItems;
+
+ KListView *categoryView;
+ KListView *unitView;
+
+ QString selected_category;
+ bool block_unit_convert;
+
+public slots:
+
+ void updateUnitTree();
+ void unitSelected();
+ void categorySelected();
+
+signals:
+
+ void unitsChanged();
+
+};
+
+#endif
diff --git a/src/qalculatedatasetsdialog.cpp b/src/qalculatedatasetsdialog.cpp
new file mode 100644
index 0000000..4468788
--- /dev/null
+++ b/src/qalculatedatasetsdialog.cpp
@@ -0,0 +1,506 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculatedatasetsdialog.h"
+
+#include "qalculateeditdatasetdialog.h"
+#include "qalculateeditdataobjectdialog.h"
+#include "qalculate_kde_utils.h"
+#include "qalculatebuttonwithdata.h"
+#include <kpushbutton.h>
+#include <qsplitter.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qgrid.h>
+#include <klistview.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <qlayout.h>
+#include <qgroupbox.h>
+#include <qscrollview.h>
+#include <ktextbrowser.h>
+#include <qlabel.h>
+#include <kactivelabel.h>
+#include <kiconloader.h>
+#include <klineedit.h>
+
+extern PrintOptions printops;
+extern QWidget *expressionWidget;
+
+QalculateDataSetsDialog::QalculateDataSetsDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Data Sets"), Close, Close, false) {
+
+ dataset_edit_dialog = NULL;
+ object_edit_dialog = NULL;
+
+ QVBox *box = makeVBoxMainWidget();
+ QSplitter *splitter = new QSplitter(Qt::Vertical, box);
+
+ QVBox *group1 = new QVBox(splitter);
+ QVBox *group2 = new QVBox(splitter);
+
+ splitter = new QSplitter(Qt::Horizontal, group1);
+ QWidget *widget = new QWidget(splitter);
+ widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
+ QVBoxLayout *vbox = new QVBoxLayout(widget, spacingHint(), spacingHint());
+ vbox->addWidget(new QLabel(i18n("Data Sets:"), widget));
+ dataSetsView = new KListView(widget);
+ vbox->addWidget(dataSetsView);
+ dataSetsView->addColumn(i18n("Data Set"));
+ dataSetsView->setRootIsDecorated(false);
+ QHBoxLayout *hbox = new QHBoxLayout(vbox);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ newDataSetButton = new QPushButton(i18n("New"), widget);
+ hbox->addWidget(newDataSetButton);
+ editDataSetButton = new QPushButton(i18n("Edit"), widget);
+ hbox->addWidget(editDataSetButton);
+ deleteDataSetButton = new QPushButton(i18n("Delete"), widget);
+ hbox->addWidget(deleteDataSetButton);
+ QVBox *vbox2 = new QVBox(splitter);
+ vbox2->setMargin(spacingHint());
+ vbox2->setSpacing(spacingHint());
+ new QLabel(i18n("Description:"), vbox2);
+ descriptionBrowser = new KTextBrowser(vbox2);
+
+ splitter = new QSplitter(Qt::Horizontal, group2);
+ widget = new QWidget(splitter);
+ widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
+ vbox = new QVBoxLayout(widget, spacingHint(), spacingHint());
+ vbox->addWidget(new QLabel(i18n("Objects:"), widget));
+ objectsView = new KListView(widget);
+ vbox->addWidget(objectsView);
+ objectsView->addColumn(i18n("Object"));
+ objectsView->setRootIsDecorated(false);
+ hbox = new QHBoxLayout(vbox);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ newObjectButton = new QPushButton(i18n("New"), widget);
+ hbox->addWidget(newObjectButton);
+ editObjectButton = new QPushButton(i18n("Edit"), widget);
+ hbox->addWidget(editObjectButton);
+ deleteObjectButton = new QPushButton(i18n("Delete"), widget);
+ hbox->addWidget(deleteObjectButton);
+ vbox2 = new QVBox(splitter);
+ vbox2->setMargin(spacingHint());
+ vbox2->setSpacing(spacingHint());
+ new QLabel(i18n("Attributes:"), vbox2);
+ attributesView = new QScrollView(vbox2);
+ attributesView->setResizePolicy(QScrollView::AutoOneFit);
+ attributesView->setFrameStyle(QFrame::NoFrame);
+ attributesGrid = new QGrid(3, Qt::Horizontal, attributesView->viewport());
+ attributesGrid->setSpacing(spacingHint());
+ attributesView->addChild(attributesGrid);
+
+ resize(QSize(675, 525).expandedTo(size()));
+
+ connect(newDataSetButton, SIGNAL(clicked()), this, SLOT(newDataSet()));
+ connect(editDataSetButton, SIGNAL(clicked()), this, SLOT(editDataSet()));
+ connect(deleteDataSetButton, SIGNAL(clicked()), this, SLOT(deleteDataSet()));
+ connect(dataSetsView, SIGNAL(selectionChanged()), this, SLOT(dataSetSelected()));
+ connect(dataSetsView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(dataSetDoubleClicked(QListViewItem*)));
+
+ connect(newObjectButton, SIGNAL(clicked()), this, SLOT(newObject()));
+ connect(editObjectButton, SIGNAL(clicked()), this, SLOT(editObject()));
+ connect(deleteObjectButton, SIGNAL(clicked()), this, SLOT(deleteObject()));
+ connect(objectsView, SIGNAL(selectionChanged()), this, SLOT(objectSelected()));
+ connect(objectsView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(objectDoubleClicked(QListViewItem*)));
+
+}
+
+QalculateDataSetsDialog::~QalculateDataSetsDialog() {}
+
+void QalculateDataSetsDialog::updateDataSetTree() {
+
+ dataSetItems.clear();
+ objectItems.clear();
+ dataSetsView->clear();
+ DataSet *ds;
+ QListViewItem *i;
+ bool b = false;
+ dataSetsView->blockSignals(true);
+ for(size_t index = 1; ; index++) {
+ ds = CALCULATOR->getDataSet(index);
+ if(!ds) break;
+ i = new KListViewItem(dataSetsView, ds->title().c_str());
+ dataSetItems[i] = ds;
+ if(ds == selected_dataset) {
+ dataSetsView->blockSignals(false);
+ dataSetsView->setSelected(i, true);
+ dataSetsView->blockSignals(true);
+ b = true;
+ }
+ }
+ dataSetsView->blockSignals(false);
+ if(!b) {
+ dataSetsView->selectAll(false);
+ selected_dataset = NULL;
+ }
+
+}
+
+#define UPDATE_SELECTED_DATASET QListViewItem *i3 = dataSetsView->selectedItem(); if(!i3) return; selected_dataset = dataSetItems[i3]; if(!selected_dataset) return;
+#define UPDATE_SELECTED_OBJECT QListViewItem *i2 = objectsView->selectedItem(); if(!i2) return; selected_object = objectItems[i2]; if(!selected_object) return;
+#define CHECK_IF_DATASET_STILL_THERE if(!CALCULATOR->stillHasFunction(selected_dataset)) {KMessageBox::error(this, i18n("Data set does not exist anymore.")); emit dataSetsChanged(); return;}
+
+void QalculateDataSetsDialog::deleteDataSet() {
+ UPDATE_SELECTED_DATASET
+ CHECK_IF_DATASET_STILL_THERE
+ if(selected_dataset->isLocal()) {
+ selected_object = NULL;
+ //ensure that all references are removed in Calculator
+ selected_dataset->destroy();
+ //update menus and trees
+ emit dataSetsChanged();
+ }
+}
+
+
+void QalculateDataSetsDialog::editDataSet() {
+ UPDATE_SELECTED_DATASET
+ CHECK_IF_DATASET_STILL_THERE
+ if(!dataset_edit_dialog) {
+ dataset_edit_dialog = new QalculateEditDataSetDialog(this);
+ }
+ DataSet *ds = dataset_edit_dialog->editDataSet(selected_dataset);
+ if(ds) {
+ selected_dataset = ds;
+ emit dataSetsChanged();
+ }
+}
+
+void QalculateDataSetsDialog::newDataSet() {
+ if(!dataset_edit_dialog) {
+ dataset_edit_dialog = new QalculateEditDataSetDialog(this);
+ }
+ DataSet *ds = dataset_edit_dialog->editDataSet();
+ if(ds) {
+ selected_dataset = ds;
+ emit dataSetsChanged();
+ }
+}
+
+void QalculateDataSetsDialog::dataSetDoubleClicked(QListViewItem*i) {
+ selected_dataset = dataSetItems[i];
+ if(!selected_dataset)
+ return;
+ CHECK_IF_DATASET_STILL_THERE
+ if(!dataset_edit_dialog) {
+ dataset_edit_dialog = new QalculateEditDataSetDialog(this);
+ }
+ DataSet *ds = dataset_edit_dialog->editDataSet(selected_dataset);
+ if(ds) {
+ selected_dataset = ds;
+ emit dataSetsChanged();
+ }
+}
+
+
+void QalculateDataSetsDialog::dataSetSelected() {
+ QListViewItem *selected = dataSetsView->selectedItem();
+ objectsView->clear();
+ if(selected) {
+ DataSet *ds = dataSetItems[selected];
+ if(!CALCULATOR->stillHasFunction(ds)) {
+ KMessageBox::error(this, i18n("Data set does not exist anymore."));
+ selected_dataset = NULL;
+ emit dataSetsChanged();
+ return;
+ }
+ //remember selection
+ selected_dataset = ds;
+
+ while(objectsView->columns() > 0) {
+ objectsView->removeColumn(0);
+ }
+
+ DataObjectIter it;
+ DataPropertyIter pit;
+ DataProperty *dp;
+ DataObject *o = ds->getFirstObject(&it);
+ bool b = false, b2 = false;
+ QListViewItem *i;
+ while(o) {
+ i = new KListViewItem(objectsView);
+ objectItems[i] = o;
+ dp = ds->getFirstProperty(&pit);
+ int index = 0;
+ while(dp) {
+ if(!dp->isHidden() && dp->isKey()) {
+ if(!b2) {
+ objectsView->addColumn(dp->title().c_str());
+ }
+ i->setText(index, o->getPropertyDisplayString(dp).c_str());
+ index++;
+ if(index > 2) break;
+ }
+ dp = ds->getNextProperty(&pit);
+ }
+ b2 = true;
+ if(o == selected_object) {
+ objectsView->setSelected(i, true);
+ b = true;
+ }
+ o = ds->getNextObject(&it);
+ }
+ if(!b) {
+ QListViewItemIterator qit(objectsView);
+ if(qit.current()) {
+ objectsView->setSelected(qit.current(), true);
+ }
+ }
+ objectsView->sort();
+
+ editDataSetButton->setEnabled(true);
+ deleteDataSetButton->setEnabled(ds->isLocal());
+ newObjectButton->setEnabled(true);
+
+ QString str, str2;
+
+ if(!ds->description().empty()) {
+ str2 = ds->description().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "<br><br>";
+ }
+ str += "<b>";
+ str += i18n("Properties");
+ str += "</b><br>";
+ dp = ds->getFirstProperty(&pit);
+ while(dp) {
+ if(!dp->isHidden()) {
+ if(!dp->title(false).empty()) {
+ str2 = dp->title().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += ": ";
+ }
+ for(size_t i = 1; i <= dp->countNames(); i++) {
+ if(i > 1) str += ", ";
+ str += dp->getName(i).c_str();
+ }
+ if(dp->isKey()) {
+ str += " (";
+ //indicating that the property is a data set key
+ str += i18n("key");
+ str += ")";
+ }
+ str += "<br>";
+ if(!dp->description().empty()) {
+ str += "<i>";
+ str2 = dp->description().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "</i><br>";
+ }
+ }
+ dp = ds->getNextProperty(&pit);
+ }
+ str += "<br><b>";
+ str += i18n("Data Retrieval Function");
+ str += "</b><br>";
+ Argument *arg;
+ Argument default_arg;
+ const ExpressionName *ename = &ds->preferredName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) descriptionBrowser);
+ str += "<i><b>";
+ str += ename->name.c_str();
+ str += "</b>";
+ int iargs = ds->maxargs();
+ if(iargs < 0) {
+ iargs = ds->minargs() + 1;
+ }
+ str += "(";
+ if(iargs != 0) {
+ for(int i2 = 1; i2 <= iargs; i2++) {
+ if(i2 > ds->minargs()) {
+ str += "[";
+ }
+ if(i2 > 1) {
+ str += CALCULATOR->getComma().c_str();
+ str += " ";
+ }
+ arg = ds->getArgumentDefinition(i2);
+ if(arg && !arg->name().empty()) {
+ str += arg->name().c_str();
+ } else {
+ str += i18n("argument");
+ str += " ";
+ str += QString::number(i2);
+ }
+ if(i2 > ds->minargs()) {
+ str += "]";
+ }
+ }
+ if(ds->maxargs() < 0) {
+ str += CALCULATOR->getComma().c_str();
+ str += " ...";
+ }
+ }
+ str += ")";
+ for(size_t i2 = 1; i2 <= ds->countNames(); i2++) {
+ if(&ds->getName(i2) != ename) {
+ str += "<br>";
+ str += ds->getName(i2).name.c_str();
+ }
+ }
+ str += "</i>";
+ str += "<br>";
+
+ if(!ds->copyright().empty()) {
+ str += "<br>";
+ str2 = ds->copyright().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "<br>";
+ }
+ str.replace("\n", "<br>");
+ descriptionBrowser->setText(str);
+
+ } else {
+ editDataSetButton->setEnabled(false);
+ deleteDataSetButton->setEnabled(false);
+ newObjectButton->setEnabled(false);
+ selected_dataset = NULL;
+ descriptionBrowser->clear();
+ }
+ objectSelected();
+}
+
+void QalculateDataSetsDialog::insertObjectData(void *data) {
+ DataProperty *dp = (DataProperty*) data;
+ DataSet *ds = dp->parentSet();
+ if(ds && selected_object) {
+ QString str = ds->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionWidget).name.c_str();
+ str += "(";
+ str += selected_object->getProperty(ds->getPrimaryKeyProperty()).c_str();
+ str += CALCULATOR->getComma().c_str();
+ str += " ";
+ str += dp->getName().c_str();
+ str += ")";
+ insert_text_in_expression(str);
+ }
+}
+
+void QalculateDataSetsDialog::objectSelected() {
+
+ QListViewItem *selected = objectsView->selectedItem();
+ DataObject *o = NULL;
+ if(selected) o = objectItems[selected];
+
+ if(o) {
+ selected_object = o;
+ editObjectButton->setEnabled(true);
+ deleteObjectButton->setEnabled(true);
+ DataSet *ds = o->parentSet();
+ if(!ds) return;
+ DataPropertyIter it;
+ DataProperty *dp = ds->getFirstProperty(&it);
+ QString sval;
+ QString str;
+ delete attributesGrid;
+ attributesGrid = new QGrid(3, Qt::Horizontal, attributesView->viewport());
+ attributesGrid->setSpacing(spacingHint());
+ attributesView->addChild(attributesGrid);
+ while(dp) {
+ if(!dp->isHidden()) {
+ sval = o->getPropertyDisplayString(dp).c_str();
+ if(!sval.isEmpty()) {
+ str = "<b>"; str += dp->title().c_str(); str += ":"; str += "</b>";
+ new QLabel(str, attributesGrid);
+ KLineEdit *le = new KLineEdit(sval, attributesGrid);
+ le->setReadOnly(true);
+ le->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
+ QalculateButtonWithData *button = new QalculateButtonWithData((void*) dp, QIconSet(SmallIcon("editpaste")), "", attributesGrid);
+ QObject::connect(button, SIGNAL(clickedWithData(void*)), SLOT(insertObjectData(void*)));
+ }
+ }
+ dp = ds->getNextProperty(&it);
+ }
+ QWidget *widget = new QWidget(attributesGrid);
+ widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
+ attributesGrid->show();
+ } else {
+ delete attributesGrid;
+ attributesGrid = new QGrid(3, Qt::Horizontal, attributesView->viewport());
+ attributesGrid->setSpacing(spacingHint());
+ attributesView->addChild(attributesGrid);
+ attributesGrid->show();
+ selected_object = NULL;
+ editObjectButton->setEnabled(false);
+ deleteObjectButton->setEnabled(false);
+ }
+
+}
+
+void QalculateDataSetsDialog::deleteObject() {
+ UPDATE_SELECTED_DATASET
+ UPDATE_SELECTED_OBJECT
+ selected_dataset->delObject(selected_object);
+ selected_object = NULL;
+ updateObjects();
+}
+
+void QalculateDataSetsDialog::updateObjects() {
+ dataSetSelected();
+}
+
+void QalculateDataSetsDialog::editObject() {
+ UPDATE_SELECTED_DATASET
+ UPDATE_SELECTED_OBJECT
+ if(!object_edit_dialog) {
+ object_edit_dialog = new QalculateEditDataObjectDialog(this);
+ }
+ DataObject *o = object_edit_dialog->editDataObject(selected_dataset, selected_object);
+ if(o) {
+ selected_object = o;
+ updateObjects();
+ }
+}
+
+void QalculateDataSetsDialog::newObject() {
+ UPDATE_SELECTED_DATASET
+ if(!object_edit_dialog) {
+ object_edit_dialog = new QalculateEditDataObjectDialog(this);
+ }
+ DataObject *o = object_edit_dialog->editDataObject(selected_dataset);
+ if(o) {
+ selected_object = o;
+ updateObjects();
+ }
+}
+
+void QalculateDataSetsDialog::objectDoubleClicked(QListViewItem*i) {
+ UPDATE_SELECTED_DATASET
+ selected_object = objectItems[i];
+ if(!selected_object)
+ return;
+ if(!object_edit_dialog) {
+ object_edit_dialog = new QalculateEditDataObjectDialog(this);
+ }
+ DataObject *o = object_edit_dialog->editDataObject(selected_dataset, selected_object);
+ if(o) {
+ selected_object = o;
+ updateObjects();
+ }
+}
+
+
+
+#include "qalculatedatasetsdialog.moc"
diff --git a/src/qalculatedatasetsdialog.h b/src/qalculatedatasetsdialog.h
new file mode 100644
index 0000000..1fa85b7
--- /dev/null
+++ b/src/qalculatedatasetsdialog.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEDATASETSDIALOG_H
+#define QALCULATEDATASETSDIALOG_H
+
+#include <kdialogbase.h>
+#include <qmap.h>
+
+class QPushButton;
+class KListView;
+class KTextBrowser;
+class QScrollView;
+class QGrid;
+class DataSet;
+class DataObject;
+class QalculateEditDataSetDialog;
+class QalculateEditDataObjectDialog;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateDataSetsDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateDataSetsDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateDataSetsDialog();
+
+ QPushButton *newObjectButton, *editObjectButton, *deleteObjectButton, *newDataSetButton, *editDataSetButton, *deleteDataSetButton;
+ KListView *objectsView, *dataSetsView;
+ KTextBrowser *descriptionBrowser;
+ QScrollView *attributesView;
+ QGrid *attributesGrid;
+
+ QMap<QListViewItem*, DataSet*> dataSetItems;
+ QMap<QListViewItem*, DataObject*> objectItems;
+
+ DataSet *selected_dataset;
+ DataObject *selected_object;
+
+ QalculateEditDataSetDialog *dataset_edit_dialog;
+ QalculateEditDataObjectDialog *object_edit_dialog;
+
+public slots:
+
+ void updateDataSetTree();
+ void dataSetDoubleClicked(QListViewItem*);
+ void objectDoubleClicked(QListViewItem*);
+ void dataSetSelected();
+ void objectSelected();
+ void deleteDataSet();
+ void editDataSet();
+ void newDataSet();
+ void deleteObject();
+ void editObject();
+ void newObject();
+ void updateObjects();
+ void insertObjectData(void*);
+
+signals:
+
+ void dataSetsChanged();
+
+};
+
+#endif
diff --git a/src/qalculatedecimalsdialog.cpp b/src/qalculatedecimalsdialog.cpp
new file mode 100644
index 0000000..2039b93
--- /dev/null
+++ b/src/qalculatedecimalsdialog.cpp
@@ -0,0 +1,55 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculatedecimalsdialog.h"
+
+#include <qlabel.h>
+#include <qspinbox.h>
+#include <klocale.h>
+#include <qgrid.h>
+
+QalculateDecimalsDialog::QalculateDecimalsDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Decimals"), Close, Close, true) {
+
+ QGrid *grid = makeGridMainWidget(2, Qt::Horizontal);
+
+ new QLabel(i18n("Max decimals:"), grid);
+
+ maxDecimalsBox = new QSpinBox(grid);
+ maxDecimalsBox->setButtonSymbols(QSpinBox::PlusMinus);
+ maxDecimalsBox->setMinValue(-1);
+ maxDecimalsBox->setValue(-1);
+ maxDecimalsBox->setSpecialValueText(i18n( "Off" ));
+
+ new QLabel(i18n("Min decimals:"), grid);
+
+ minDecimalsBox = new QSpinBox(grid);
+ minDecimalsBox->setButtonSymbols(QSpinBox::PlusMinus);
+ minDecimalsBox->setMinValue(0);
+ minDecimalsBox->setValue(0);
+ minDecimalsBox->setSpecialValueText(i18n( "Off" ));
+
+ resize(QSize(300, minimumSizeHint().height()).expandedTo(minimumSizeHint()));
+
+}
+
+
+QalculateDecimalsDialog::~QalculateDecimalsDialog() {}
+
+
+#include "qalculatedecimalsdialog.moc"
diff --git a/src/qalculatedecimalsdialog.h b/src/qalculatedecimalsdialog.h
new file mode 100644
index 0000000..ae16d7c
--- /dev/null
+++ b/src/qalculatedecimalsdialog.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEDECIMALSDIALOG_H
+#define QALCULATEDECIMALSDIALOG_H
+
+#include <kdialogbase.h>
+
+class QSpinBox;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateDecimalsDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateDecimalsDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateDecimalsDialog();
+
+ QSpinBox *maxDecimalsBox, *minDecimalsBox;
+
+};
+
+#endif
diff --git a/src/qalculateeditdataobjectdialog.cpp b/src/qalculateeditdataobjectdialog.cpp
new file mode 100644
index 0000000..cf9e0cd
--- /dev/null
+++ b/src/qalculateeditdataobjectdialog.cpp
@@ -0,0 +1,103 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateeditdataobjectdialog.h"
+#include "qalculate_kde_utils.h"
+#include <qlabel.h>
+#include <qgrid.h>
+#include <klineedit.h>
+#include <kcombobox.h>
+#include <qvaluevector.h>
+#include <qstring.h>
+#include <klocale.h>
+
+QalculateEditDataObjectDialog::QalculateEditDataObjectDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Object"), Ok | Cancel, Ok, true) {
+
+}
+
+QalculateEditDataObjectDialog::~QalculateEditDataObjectDialog() {}
+
+DataObject *QalculateEditDataObjectDialog::editDataObject(DataSet *ds, DataObject *o) {
+
+ if(!ds) return NULL;
+ if(o) {
+ setCaption(i18n("Edit Object"));
+ } else {
+ setCaption(i18n("New Object"));
+ }
+
+ QGrid *grid = new QGrid(4, Qt::Horizontal, this);
+ grid->setSpacing(spacingHint());
+ setMainWidget(grid);
+ new QLabel(i18n("Property"), grid);
+ new QLabel(i18n("Value"), grid);
+ new QLabel(grid);
+ new QLabel(i18n("Approximation"), grid);
+ DataPropertyIter it;
+ DataProperty *dp = ds->getFirstProperty(&it);
+ string sval;
+ QValueVector<KLineEdit*> value_entries;
+ QValueVector<KComboBox*> approx_menus;
+ string str;
+ while(dp) {
+ new QLabel(dp->title().c_str(), grid);
+ KLineEdit *entry = new KLineEdit(grid);
+ value_entries.push_back(entry);
+ int iapprox = -1;
+ if(o) {
+ entry->setText(o->getProperty(dp, &iapprox).c_str());
+ }
+ new QLabel(dp->getUnitString().c_str(), grid);
+ KComboBox *om = new KComboBox(grid);
+ om->setEditable(false);
+ om->insertItem(i18n("Default"));
+ om->insertItem(i18n("Approximate"));
+ om->insertItem(i18n("Exact"));
+ approx_menus.push_back(om);
+ om->setCurrentItem(iapprox + 1);
+ dp = ds->getNextProperty(&it);
+ }
+ if(exec() == QDialog::Accepted) {
+ bool new_object = (o == NULL);
+ if(new_object) {
+ o = new DataObject(ds);
+ ds->addObject(o);
+ }
+ dp = ds->getFirstProperty(&it);
+ size_t i = 0;
+ QString val;
+ while(dp) {
+ val = value_entries[i]->text().stripWhiteSpace();
+ if(!val.isEmpty()) {
+ o->setProperty(dp, val.ascii(), approx_menus[i]->currentItem() - 1);
+ } else if(!new_object) {
+ o->eraseProperty(dp);
+ }
+ dp = ds->getNextProperty(&it);
+ i++;
+ }
+ o->setUserModified();
+ delete grid;
+ return o;
+ }
+ delete grid;
+ return NULL;
+}
+
+#include "qalculateeditdataobjectdialog.moc"
diff --git a/src/qalculateeditdataobjectdialog.h b/src/qalculateeditdataobjectdialog.h
new file mode 100644
index 0000000..9db334b
--- /dev/null
+++ b/src/qalculateeditdataobjectdialog.h
@@ -0,0 +1,44 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEEDITDATAOBJECTDIALOG_H
+#define QALCULATEEDITDATAOBJECTDIALOG_H
+
+#include <kdialogbase.h>
+
+class DataObject;
+class DataSet;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateEditDataObjectDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateEditDataObjectDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateEditDataObjectDialog();
+
+ DataObject *editDataObject(DataSet *ds, DataObject *o = NULL);
+
+};
+
+#endif
diff --git a/src/qalculateeditdatasetdialog.cpp b/src/qalculateeditdatasetdialog.cpp
new file mode 100644
index 0000000..3341395
--- /dev/null
+++ b/src/qalculateeditdatasetdialog.cpp
@@ -0,0 +1,750 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateeditdatasetdialog.h"
+#include "qalculate_kde_utils.h"
+#include "qalculateeditnamesdialog.h"
+
+#include <qgrid.h>
+#include <klineedit.h>
+#include <kpushbutton.h>
+#include <kcombobox.h>
+#include <qlabel.h>
+#include <klocale.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qcheckbox.h>
+#include <kmessagebox.h>
+#include <kdeversion.h>
+#include <qlayout.h>
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
+#include <qtextedit.h>
+#else
+#include <ktextedit.h>
+#endif
+#include <klistview.h>
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+#include <qtabwidget.h>
+#else
+#include <ktabwidget.h>
+#endif
+#include <qapplication.h>
+#include <kstdguiitem.h>
+
+extern PrintOptions printops;
+extern tree_struct function_cats;
+
+QalculateEditDataSetDialog::QalculateEditDataSetDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Data Set"), Ok | Cancel, Ok, false) {
+
+ names_edit_dialog = NULL;
+ edited_dataset = NULL;
+ property_edit_dialog = NULL;
+
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ tabs = new QTabWidget(this);
+#else
+ tabs = new KTabWidget(this);
+#endif
+ setMainWidget(tabs);
+ QWidget *page1 = new QWidget(this);
+ QWidget *page2 = new QWidget(this);
+ QWidget *page3 = new QWidget(this);
+ tabs->addTab(page1, i18n("General"));
+ tabs->addTab(page2, i18n("Properties"));
+ tabs->addTab(page3, i18n("Function"));
+
+ QGridLayout *grid = new QGridLayout(page1, 1, 1, spacingHint());
+ grid->addWidget(new QLabel(i18n("Title:"), page1), 0, 0);
+ titleEdit = new KLineEdit(page1);
+ grid->addWidget(titleEdit, 0, 1);
+ grid->addWidget(new QLabel(i18n("Data file:"), page1), 1, 0);
+ fileEdit = new KLineEdit(page1);
+ grid->addWidget(fileEdit, 1, 1);
+ grid->addWidget(new QLabel(i18n("Description:"), page1), 2, 0);
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
+ descriptionEdit = new QTextEdit(page1);
+#else
+ descriptionEdit = new KTextEdit(page1);
+#endif
+ descriptionEdit->setTextFormat(QTextEdit::PlainText);
+ grid->addMultiCellWidget(descriptionEdit, 3, 3, 0, 1);
+ grid->addWidget(new QLabel(i18n("Copyright:"), page1), 4, 0);
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
+ copyrightEdit = new QTextEdit(page1);
+#else
+ copyrightEdit = new KTextEdit(page1);
+#endif
+ copyrightEdit->setTextFormat(QTextEdit::PlainText);
+ grid->addMultiCellWidget(copyrightEdit, 5, 5, 0, 1);
+
+ QVBoxLayout *vbox = new QVBoxLayout(page2, spacingHint());
+ vbox->addWidget(new QLabel(i18n("Properties:"), page2));
+ propertiesView = new KListView(page2);
+ propertiesView->addColumn(i18n("Title"));
+ propertiesView->addColumn(i18n("Name"));
+ propertiesView->addColumn(i18n("Type"));
+ propertiesView->setSorting(-1);
+ propertiesView->setRootIsDecorated(false);
+ vbox->addWidget(propertiesView);
+ QHBoxLayout *hbox = new QHBoxLayout(vbox, spacingHint());
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ newPropertyButton = new QPushButton(i18n("New"), page2);
+ hbox->addWidget(newPropertyButton);
+ editPropertyButton = new QPushButton(i18n("Edit"), page2);
+ hbox->addWidget(editPropertyButton);
+ deletePropertyButton = new QPushButton(i18n("Delete"), page2);
+ hbox->addWidget(deletePropertyButton);
+
+ grid = new QGridLayout(page3, 1, 1, spacingHint());
+ grid->addWidget(new QLabel(i18n("Name:"), page3), 0, 0);
+ nameEdit = new KLineEdit(page3);
+ grid->addWidget(nameEdit, 0, 1);
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
+ namesLabel = new QLabel(page3);
+ namesLabel->setAlignment(Qt::AlignRight);
+ namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ hbox->addWidget(namesLabel);
+ namesButton = new QPushButton(i18n("Names Details"), page3);
+ hbox->addWidget(namesButton);
+ grid->addWidget(new QLabel(i18n("Object argument name:"), page3), 2, 0);
+ objectArgumentEdit = new KLineEdit(page3);
+ grid->addWidget(objectArgumentEdit, 2, 1);
+ grid->addWidget(new QLabel(i18n("Property argument name:"), page3), 3, 0);
+ propertyArgumentEdit = new KLineEdit(page3);
+ grid->addWidget(propertyArgumentEdit, 3, 1);
+ grid->addWidget(new QLabel(i18n("Default property:"), page3), 4, 0);
+ defaultPropertyEdit = new KLineEdit(page3);
+ grid->addWidget(defaultPropertyEdit, 4, 1);
+ grid->addItem(new QSpacerItem(5, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
+
+
+ connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
+ connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
+ connect(newPropertyButton, SIGNAL(clicked()), this, SLOT(newProperty()));
+ connect(editPropertyButton, SIGNAL(clicked()), this, SLOT(editProperty()));
+ connect(deletePropertyButton, SIGNAL(clicked()), this, SLOT(deleteProperty()));
+ connect(propertiesView, SIGNAL(selectionChanged()), this, SLOT(propertySelectionChanged()));
+
+}
+
+QalculateEditDataSetDialog::~QalculateEditDataSetDialog() {}
+
+
+void QalculateEditDataSetDialog::propertySelectionChanged() {
+ QListViewItem *i = propertiesView->selectedItem();
+ if(i) {
+ editPropertyButton->setEnabled(propertiesItems[i]->isUserModified());
+ deletePropertyButton->setEnabled(propertiesItems[i]->isUserModified());
+ } else {
+ editPropertyButton->setEnabled(false);
+ deletePropertyButton->setEnabled(false);
+ }
+}
+
+void QalculateEditDataSetDialog::updateDatasetPropertyList() {
+ propertiesView->clear();
+ propertiesItems.clear();
+ editPropertyButton->setEnabled(false);
+ deletePropertyButton->setEnabled(false);
+ QString str;
+ QListViewItem *i_prev = NULL;
+ for(size_t i = 0; i < tmp_props.size(); i++) {
+ if(tmp_props[i]) {
+ str = "";
+ switch(tmp_props[i]->propertyType()) {
+ case PROPERTY_STRING: {
+ str += i18n("text");
+ break;
+ }
+ case PROPERTY_NUMBER: {
+ if(tmp_props[i]->isApproximate()) {
+ str += i18n("approximate");
+ str += " ";
+ }
+ str += i18n("number");
+ break;
+ }
+ case PROPERTY_EXPRESSION: {
+ if(tmp_props[i]->isApproximate()) {
+ str += i18n("approximate");
+ str += " ";
+ }
+ str += i18n("expression");
+ break;
+ }
+ }
+ if(tmp_props[i]->isKey()) {
+ str += " (";
+ str += i18n("key");
+ str += ")";
+ }
+ QListViewItem *item = new KListViewItem(propertiesView, i_prev, tmp_props[i]->title(false).c_str(), tmp_props[i]->getName().c_str(), str);
+ i_prev = item;
+ propertiesItems[item] = tmp_props[i];
+ }
+ }
+}
+
+void QalculateEditDataSetDialog::slotOk() {
+
+ string str = nameEdit->text().ascii();
+ remove_blank_ends(str);
+ if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
+ //no name -- open dialog again
+ tabs->setCurrentPage(2);
+ nameEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty name field"));
+ return;
+ }
+ //function with the same name exists -- overwrite or open dialog again
+ if((!edited_dataset || !edited_dataset->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->functionNameTaken(str, edited_dataset) && KMessageBox::questionYesNo(this, i18n("A function with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
+ tabs->setCurrentPage(2);
+ nameEdit->setFocus();
+ return;
+ }
+
+ DataSet *ds = edited_dataset;
+ bool add_func = false;
+ if(ds) {
+ //edited an existing function
+ ds->setTitle(titleEdit->text().ascii());
+ ds->setDescription(descriptionEdit->text().ascii());
+ if(ds->isLocal()) ds->setDefaultDataFile(fileEdit->text().ascii());
+ } else {
+ //new function
+ ds = new DataSet(i18n("Data Sets").ascii(), "", fileEdit->text().ascii(), titleEdit->text().ascii(), descriptionEdit->text().ascii(), true);
+ add_func = true;
+ }
+ QString str2 = objectArgumentEdit->text().stripWhiteSpace();
+ if(str2.isEmpty()) str2 = i18n("Object");
+ Argument *arg = ds->getArgumentDefinition(1);
+ if(arg) {
+ arg->setName(str2.ascii());
+ }
+ str2 = propertyArgumentEdit->text().stripWhiteSpace();
+ if(str2.isEmpty()) str2 = i18n("Property");
+ arg = ds->getArgumentDefinition(2);
+ if(arg) {
+ arg->setName(str2.ascii());
+ }
+ ds->setDefaultProperty(defaultPropertyEdit->text().ascii());
+ ds->setCopyright(copyrightEdit->text().ascii());
+ DataPropertyIter it;
+ for(size_t i = 0; i < tmp_props.size();) {
+ if(!tmp_props[i]) {
+ if(tmp_props_orig[i]) ds->delProperty(tmp_props_orig[i]);
+ i++;
+ } else if(tmp_props[i]->isUserModified()) {
+ if(tmp_props_orig[i]) {
+ tmp_props_orig[i]->set(*tmp_props[i]);
+ i++;
+ } else {
+ ds->addProperty(tmp_props[i]);
+ tmp_props.erase(tmp_props.begin() + i);
+ }
+ } else {
+ i++;
+ }
+ }
+
+ if(names_edit_dialog) {
+ names_edit_dialog->saveNames(ds, str.c_str());
+ } else {
+ if(ds->countNames() == 0) {
+ ExpressionName ename(str);
+ ename.reference = true;
+ ds->setName(ename, 1);
+ } else {
+ ds->setName(str, 1);
+ }
+ }
+ if(add_func) {
+ CALCULATOR->addDataSet(ds);
+ ds->loadObjects();
+ ds->setObjectsLoaded(true);
+ }
+
+ for(size_t i = 0; i < tmp_props.size(); i++) {
+ if(tmp_props[i]) delete tmp_props[i];
+ }
+ tmp_props.clear();
+ tmp_props_orig.clear();
+ edited_dataset = ds;
+
+ accept();
+
+}
+
+DataSet *QalculateEditDataSetDialog::editDataSet(DataSet *ds) {
+
+ titleEdit->setFocus();
+
+ tabs->setCurrentPage(0);
+ if(names_edit_dialog) {
+ delete names_edit_dialog;
+ names_edit_dialog = NULL;
+ }
+ edited_dataset = ds;
+ if(ds) {
+ if(ds->isLocal())
+ setCaption(i18n("Edit Data Set"));
+ else
+ setCaption(i18n("Edit Data Set (global)"));
+ } else {
+ setCaption(i18n("New Data Set"));
+ }
+
+ //clear entries
+ fileEdit->setReadOnly(ds && !ds->isLocal());
+ copyrightEdit->setReadOnly(ds && !ds->isLocal());
+ nameEdit->clear();
+ titleEdit->clear();
+ fileEdit->clear();
+ objectArgumentEdit->clear();
+ propertyArgumentEdit->clear();
+ defaultPropertyEdit->setText(i18n("info"));
+ namesLabel->clear();
+ descriptionEdit->clear();
+ copyrightEdit->clear();
+ nameEdit->setReadOnly(false);
+ actionButton(Ok)->setEnabled(true);
+ newPropertyButton->setEnabled(TRUE);
+ editPropertyButton->setEnabled(FALSE);
+ deletePropertyButton->setEnabled(FALSE);
+ if(ds) {
+ //fill in original paramaters
+ set_name_label_and_entry(ds, nameEdit, namesLabel);
+ fileEdit->setText(ds->defaultDataFile().c_str());
+ defaultPropertyEdit->setText(ds->defaultProperty().c_str());
+ titleEdit->setText(ds->title(false).c_str());
+ Argument *arg = ds->getArgumentDefinition(1);
+ if(arg) {
+ objectArgumentEdit->setText(arg->name().c_str());
+ }
+ arg = ds->getArgumentDefinition(2);
+ if(arg) {
+ propertyArgumentEdit->setText(arg->name().c_str());
+ }
+ descriptionEdit->setText(ds->description().c_str());
+ copyrightEdit->setText(ds->copyright().c_str());
+ DataPropertyIter it;
+ DataProperty *dp = ds->getFirstProperty(&it);
+ while(dp) {
+ tmp_props.push_back(new DataProperty(*dp));
+ tmp_props_orig.push_back(dp);
+ dp = ds->getNextProperty(&it);
+ }
+ }
+ updateDatasetPropertyList();
+
+ if(exec() == QDialog::Accepted) {
+ ds = edited_dataset;
+ edited_dataset = NULL;
+ return ds;
+ }
+ edited_dataset = NULL;
+ for(size_t i = 0; i < tmp_props.size(); i++) {
+ if(tmp_props[i]) delete tmp_props[i];
+ }
+ tmp_props.clear();
+ tmp_props_orig.clear();
+ return NULL;
+}
+
+void QalculateEditDataSetDialog::editNames() {
+ if(!names_edit_dialog) {
+ names_edit_dialog = new QalculateEditNamesDialog(TYPE_FUNCTION, this);
+ names_edit_dialog->setNames(edited_dataset, nameEdit->text(), false);
+ } else {
+ names_edit_dialog->setNames(edited_dataset, nameEdit->text(), true);
+ }
+ names_edit_dialog->exec();
+ names_edit_dialog->setNamesLE(nameEdit, namesLabel);
+}
+void QalculateEditDataSetDialog::newProperty() {
+ if(!property_edit_dialog) {
+ property_edit_dialog = new QalculateEditDataPropertyDialog(this);
+ }
+ DataProperty *dp = new DataProperty(edited_dataset);
+ dp->setUserModified(true);
+ if(property_edit_dialog->editDataProperty(dp, true)) {
+ tmp_props.push_back(dp);
+ tmp_props_orig.push_back(NULL);
+ updateDatasetPropertyList();
+ } else {
+ delete dp;
+ }
+}
+
+void QalculateEditDataSetDialog::editProperty() {
+ QListViewItem *i = propertiesView->selectedItem();
+ if(i == NULL) return;
+ if(!property_edit_dialog) {
+ property_edit_dialog = new QalculateEditDataPropertyDialog(this);
+ }
+ if(property_edit_dialog->editDataProperty(propertiesItems[i])) {
+ updateDatasetPropertyList();
+ }
+}
+void QalculateEditDataSetDialog::deleteProperty() {
+ QListViewItem *i = propertiesView->selectedItem();
+ if(i == NULL) return;
+ if(propertiesItems[i]->isUserModified()) {
+ for(size_t index = 0; index < tmp_props.size(); index++) {
+ if(tmp_props[index] == propertiesItems[i]) {
+ if(tmp_props_orig[index]) {
+ tmp_props[index] = NULL;
+ } else {
+ tmp_props.erase(tmp_props.begin() + index);
+ tmp_props_orig.erase(tmp_props_orig.begin() + index);
+ }
+ break;
+ }
+ }
+ updateDatasetPropertyList();
+ }
+}
+
+void QalculateEditDataSetDialog::nameChanged(const QString &name) {
+ if(name.isNull()) return;
+ if(!CALCULATOR->functionNameIsValid(name.ascii())) {
+ nameEdit->blockSignals(true);
+ nameEdit->setText(CALCULATOR->convertToValidFunctionName(name.ascii()).c_str());
+ nameEdit->blockSignals(false);
+ }
+}
+
+
+QalculateEditDataPropertyDialog::QalculateEditDataPropertyDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Property"), Ok | Cancel, Ok, true) {
+
+ names_edit_dialog = NULL;
+ edited_property = NULL;
+
+ setMainWidget(new QWidget(this));
+ QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
+ grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 0, 0);
+ nameEdit = new KLineEdit(mainWidget());
+ grid->addWidget(nameEdit, 0, 1);
+ QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
+ namesLabel = new QLabel(mainWidget());
+ namesLabel->setAlignment(Qt::AlignRight);
+ namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ hbox->addWidget(namesLabel);
+ namesButton = new QPushButton(i18n("Names Details"), mainWidget());
+ hbox->addWidget(namesButton);
+ grid->addWidget(new QLabel(i18n("Descriptive name:"), mainWidget()), 2, 0);
+ titleEdit = new KLineEdit(mainWidget());
+ grid->addWidget(titleEdit, 2, 1);
+ grid->addWidget(new QLabel(i18n("Description:"), mainWidget()), 3, 0);
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
+ descriptionEdit = new QTextEdit(mainWidget());
+#else
+ descriptionEdit = new KTextEdit(mainWidget());
+#endif
+ descriptionEdit->setTextFormat(QTextEdit::PlainText);
+ grid->addMultiCellWidget(descriptionEdit, 4, 4, 0, 1);
+ grid->addWidget(new QLabel(i18n("Value type:"), mainWidget()), 5, 0);
+ typeCombo = new KComboBox(mainWidget());
+ typeCombo->setEditable(false);
+ typeCombo->insertItem(i18n("Text"));
+ typeCombo->insertItem(i18n("Number"));
+ typeCombo->insertItem(i18n("Expression"));
+ grid->addWidget(typeCombo, 5, 1);
+ hideButton = new QCheckBox(i18n("Hide"), mainWidget());
+ grid->addWidget(hideButton, 6, 0);
+ //Use as a unique data set key
+ keyButton = new QCheckBox(i18n("Use as key"), mainWidget());
+ grid->addWidget(keyButton, 6, 1);
+ approximateButton = new QCheckBox(i18n("Approximate value"), mainWidget());
+ grid->addWidget(approximateButton, 7, 0);
+ caseButton = new QCheckBox(i18n("Case sensitive value"), mainWidget());
+ grid->addWidget(caseButton, 7, 1);
+ bracketsButton = new QCheckBox(i18n("Value uses brackets"), mainWidget());
+ grid->addWidget(bracketsButton, 8, 0);
+ grid->addWidget(new QLabel(i18n("Unit expression:"), mainWidget()), 9, 0);
+ unitEdit = new KLineEdit(mainWidget());
+ grid->addWidget(unitEdit, 9, 1);
+
+ connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
+
+}
+
+QalculateEditDataPropertyDialog::~QalculateEditDataPropertyDialog() {}
+
+void QalculateEditDataPropertyDialog::slotOk() {
+
+ string str = nameEdit->text().ascii();
+ remove_blank_ends(str);
+ if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
+ //no name -- open dialog again
+ nameEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty name field"));
+ return;
+ }
+ DataProperty *dp = edited_property;
+ dp->setTitle(titleEdit->text().ascii());
+ dp->setUnit(unitEdit->text().ascii());
+
+ dp->setHidden(hideButton->isChecked());
+ dp->setKey(keyButton->isChecked());
+ dp->setApproximate(approximateButton->isChecked());
+ dp->setCaseSensitive(caseButton->isChecked());
+ dp->setUsesBrackets(bracketsButton->isChecked());
+
+ dp->setDescription(descriptionEdit->text().ascii());
+
+ switch(typeCombo->currentItem()) {
+ case 0: {
+ dp->setPropertyType(PROPERTY_STRING);
+ break;
+ }
+ case 1: {
+ dp->setPropertyType(PROPERTY_NUMBER);
+ break;
+ }
+ case 2: {
+ dp->setPropertyType(PROPERTY_EXPRESSION);
+ break;
+ }
+ }
+ if(names_edit_dialog) {
+ names_edit_dialog->saveNames(dp, str.c_str());
+ } else {
+ dp->setName(str, 1);
+ }
+ edited_property = dp;
+ accept();
+
+}
+
+bool QalculateEditDataPropertyDialog::editDataProperty(DataProperty *dp, bool newdp) {
+
+ nameEdit->setFocus();
+
+ if(names_edit_dialog) {
+ delete names_edit_dialog;
+ names_edit_dialog = NULL;
+ }
+ edited_property = dp;
+ if(!newdp) {
+ setCaption(i18n("Edit Property"));
+ } else {
+ setCaption(i18n("New Property"));
+ }
+
+ actionButton(Ok)->setEnabled(true);
+
+ nameEdit->setText(dp->getName().c_str());
+ if(dp->countNames() > 1) {
+ QString str = "+ ";
+ for(size_t i = 2; i <= dp->countNames(); i++) {
+ if(i > 2) str += ", ";
+ str += dp->getName(i).c_str();
+ }
+ namesLabel->setText(str);
+ } else {
+ namesLabel->clear();
+ }
+
+ titleEdit->setText(dp->title(false).c_str());
+ unitEdit->setText(dp->getUnitString().c_str());
+
+ hideButton->setChecked(dp->isHidden());
+ keyButton->setChecked(dp->isKey());
+ approximateButton->setChecked(dp->isApproximate());
+ caseButton->setChecked(dp->isCaseSensitive());
+ bracketsButton->setChecked(dp->usesBrackets());
+
+ descriptionEdit->setText(dp->description().c_str());
+
+ switch(dp->propertyType()) {
+ case PROPERTY_STRING: {
+ typeCombo->setCurrentItem(0);
+ break;
+ }
+ case PROPERTY_NUMBER: {
+ typeCombo->setCurrentItem(1);
+ break;
+ }
+ case PROPERTY_EXPRESSION: {
+ typeCombo->setCurrentItem(2);
+ break;
+ }
+ }
+
+ if(exec() == QDialog::Accepted) {
+ edited_property = NULL;
+ return true;
+ }
+ edited_property = NULL;
+ return false;
+}
+
+void QalculateEditDataPropertyDialog::editNames() {
+ if(!names_edit_dialog) {
+ names_edit_dialog = new QalculateEditDataPropertyNamesDialog(this);
+ names_edit_dialog->setNames(edited_property, nameEdit->text(), false);
+ } else {
+ names_edit_dialog->setNames(edited_property, nameEdit->text(), true);
+ }
+ names_edit_dialog->exec();
+ names_edit_dialog->setNamesLE(nameEdit, namesLabel);
+}
+
+
+QalculateEditDataPropertyNamesDialog::QalculateEditDataPropertyNamesDialog(QWidget *parent, const char *name) : KDialog(parent, name, true) {
+
+ setCaption(i18n("Edit Names"));
+
+ QVBoxLayout *layout = new QVBoxLayout(this, marginHint(), spacingHint());
+
+ namesView = new KListView(this);
+ namesView->addColumn(i18n("Name"));
+ namesView->addColumn(i18n("Reference"));
+ namesView->setColumnAlignment(1, Qt::AlignCenter);
+ namesView->setSorting(-1);
+ namesView->setItemsRenameable(true);
+ namesView->setItemsMovable(true);
+ layout->addWidget(namesView);
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout(layout, spacingHint());
+ newButton = new QPushButton(i18n("New"), this);
+ buttonLayout->addWidget(newButton);
+ deleteButton = new QPushButton(i18n("Delete"), this);
+ deleteButton->setEnabled(false);
+ buttonLayout->addWidget(deleteButton);
+ buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ buttonClose = new KPushButton(KStdGuiItem::close(), this);
+ buttonClose->setAutoDefault(true);
+ buttonClose->setDefault(true);
+ buttonLayout->addWidget(buttonClose);
+
+ connect(namesView, SIGNAL(selectionChanged()), this, SLOT(nameSelectionChanged()));
+ connect(buttonClose, SIGNAL(clicked()), this, SLOT(accept()));
+ connect(newButton, SIGNAL(clicked()), this, SLOT(newName()));
+ connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteName()));
+ connect(namesView, SIGNAL(clicked(QListViewItem*, const QPoint&, int)), this, SLOT(itemClicked(QListViewItem*, const QPoint&, int)));
+
+}
+
+QalculateEditDataPropertyNamesDialog::~QalculateEditDataPropertyNamesDialog() {}
+
+void QalculateEditDataPropertyNamesDialog::newName() {
+ ExpressionName name;
+ QListViewItem *i = new KListViewItem(namesView, namesView->lastChild(), "", i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"));
+ namesView->setSelected(i, true);
+ qApp->processEvents();
+ namesView->rename(i, 0);
+}
+
+void QalculateEditDataPropertyNamesDialog::setNames(DataProperty *item, const QString &namestr, bool names_edited) {
+
+ if(!names_edited) {
+ deleteButton->setEnabled(false);
+ namesView->clear();
+ }
+ if(!names_edited && item && item->countNames() > 0) {
+ QListViewItem *i_prev = NULL;
+ for(size_t index = 1; index <= item->countNames(); index++) {
+ QListViewItem *i = new KListViewItem(namesView, i_prev);
+ i_prev = i;
+ if(item->nameIsReference(index))
+ i->setText(1, i18n("Yes"));
+ else
+ i->setText(1, i18n("No"));
+ if(index == 1 && !namestr.isEmpty()) {
+ i->setText(0, namestr);
+ } else {
+ i->setText(0, item->getName(index).c_str());
+ }
+ }
+ } else if(!namestr.isEmpty()) {
+ if(names_edited) {
+ QListViewItemIterator it(namesView);
+ if(it.current())
+ it.current()->setText(0, namestr);
+ } else {
+ new KListViewItem(namesView, namestr, i18n("No"));
+ }
+ }
+}
+void QalculateEditDataPropertyNamesDialog::saveNames(DataProperty *item, const QString &str) {
+ item->clearNames();
+ QListViewItemIterator it(namesView);
+ if(it.current()) {
+ bool b = false;
+ while(it.current()) {
+ bool ref = (it.current()->text(1) == i18n("Yes"));
+ if(b || str.isEmpty())
+ item->addName(it.current()->text(0).ascii(), ref);
+ else
+ item->addName(str.ascii(), ref);
+ ++it;
+ b = true;
+ }
+ } else {
+ item->addName(str.ascii());
+ }
+}
+void QalculateEditDataPropertyNamesDialog::setNamesLE(QLineEdit *entry, QLabel *label) {
+ int index = 0;
+ QString str;
+ QListViewItemIterator it(namesView);
+ while(it.current()) {
+ if(index == 0) {
+ entry->setText(it.current()->text(0));
+ } else {
+ if(index == 1) {
+ str = "+ ";
+ } else {
+ str += ", ";
+ }
+ str += it.current()->text(0);
+ }
+ ++it;
+ index++;
+ }
+ label->setText(str);
+}
+bool QalculateEditDataPropertyNamesDialog::isEmpty() {
+ return namesView->childCount() <= 0;
+}
+
+void QalculateEditDataPropertyNamesDialog::deleteName() {
+ namesView->removeItem(namesView->selectedItem());
+}
+
+void QalculateEditDataPropertyNamesDialog::itemClicked(QListViewItem *i, const QPoint &, int c) {
+ if(i && c > 0) {
+ if(i->text(c) == i18n("Yes"))
+ i->setText(c, i18n("No"));
+ else
+ i->setText(c, i18n("Yes"));
+ }
+}
+
+void QalculateEditDataPropertyNamesDialog::nameSelectionChanged() {
+ deleteButton->setEnabled(namesView->selectedItem() != NULL);
+}
+
+
+#include "qalculateeditdatasetdialog.moc"
+
diff --git a/src/qalculateeditdatasetdialog.h b/src/qalculateeditdatasetdialog.h
new file mode 100644
index 0000000..2c27b65
--- /dev/null
+++ b/src/qalculateeditdatasetdialog.h
@@ -0,0 +1,145 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEEDITDATASETDIALOG_H
+#define QALCULATEEDITDATASETDIALOG_H
+
+#include <kdialogbase.h>
+#include <qmap.h>
+#include <qvaluevector.h>
+
+class KLineEdit;
+class QCheckBox;
+class KComboBox;
+class QPushButton;
+class MathStructure;
+class QalculateEditNamesDialog;
+class DataSet;
+class KListView;
+class QTextEdit;
+class DataProperty;
+class QTabWidget;
+class UserFunction;
+class QalculateEditDataPropertyDialog;
+class QalculateEditDataPropertyNamesDialog;
+class QLineEdit;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateEditDataSetDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateEditDataSetDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateEditDataSetDialog();
+
+ DataSet *editDataSet(DataSet *ds = NULL);
+ void updateDatasetPropertyList();
+
+ QalculateEditNamesDialog *names_edit_dialog;
+ QalculateEditDataPropertyDialog *property_edit_dialog;
+ DataSet *edited_dataset;
+ KLineEdit *objectArgumentEdit, *propertyArgumentEdit, *defaultPropertyEdit, *nameEdit, *titleEdit, *fileEdit;
+ QLabel *namesLabel;
+ KListView *propertiesView;
+ QTextEdit *descriptionEdit, *copyrightEdit;
+ QPushButton *namesButton, *newPropertyButton, *editPropertyButton, *deletePropertyButton;
+ QTabWidget *tabs;
+ QMap<QListViewItem*, DataProperty*> propertiesItems;
+ QValueVector<DataProperty*> tmp_props;
+ QValueVector<DataProperty*> tmp_props_orig;
+
+public slots:
+
+ void propertySelectionChanged();
+ void editNames();
+ void newProperty();
+ void editProperty();
+ void deleteProperty();
+ void nameChanged(const QString&);
+
+protected slots:
+
+ void slotOk();
+
+};
+
+class QalculateEditDataPropertyDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateEditDataPropertyDialog(QWidget *parent = 0, const char *name = 0);
+ ~QalculateEditDataPropertyDialog();
+
+ bool editDataProperty(DataProperty *dp, bool newdp = false);
+
+ QalculateEditDataPropertyNamesDialog *names_edit_dialog;
+ DataProperty *edited_property;
+ KComboBox *typeCombo;
+ KLineEdit *nameEdit, *titleEdit, *unitEdit;
+ QLabel *namesLabel;
+ QCheckBox *hideButton, *keyButton, *approximateButton, *caseButton, *bracketsButton;
+ QPushButton *namesButton;
+ QTextEdit *descriptionEdit;
+
+public slots:
+
+ void editNames();
+
+protected slots:
+
+ void slotOk();
+
+};
+
+class QalculateEditDataPropertyNamesDialog : public KDialog {
+
+ Q_OBJECT
+
+public:
+
+ QalculateEditDataPropertyNamesDialog(QWidget *parent = 0, const char *name = 0);
+ ~QalculateEditDataPropertyNamesDialog();
+
+ void saveNames(DataProperty *item, const QString &str = QString::null);
+ void setNames(DataProperty *item = NULL, const QString &namestr = QString::null, bool names_edited = false);
+ bool isEmpty();
+ void setNamesLE(QLineEdit *entry, QLabel *label);
+
+ KListView* namesView;
+ QPushButton* newButton;
+ QPushButton* deleteButton;
+ QPushButton* buttonClose;
+ int i_type;
+
+public slots:
+
+ void itemClicked(QListViewItem*, const QPoint&, int);
+ void newName();
+ void deleteName();
+ void nameSelectionChanged();
+
+};
+
+#endif
diff --git a/src/qalculateeditfunctiondialog.cpp b/src/qalculateeditfunctiondialog.cpp
new file mode 100644
index 0000000..f82b0cb
--- /dev/null
+++ b/src/qalculateeditfunctiondialog.cpp
@@ -0,0 +1,799 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateeditfunctiondialog.h"
+#include "qalculate_kde_utils.h"
+#include "qalculateeditnamesdialog.h"
+
+#include <qgrid.h>
+#include <klineedit.h>
+#include <kpushbutton.h>
+#include <kcombobox.h>
+#include <qlabel.h>
+#include <klocale.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qcheckbox.h>
+#include <kmessagebox.h>
+#include <qlayout.h>
+#include <kdeversion.h>
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
+#include <qtextedit.h>
+#else
+#include <ktextedit.h>
+#endif
+#include <klistview.h>
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+#include <qtabwidget.h>
+#else
+#include <ktabwidget.h>
+#endif
+#include <qheader.h>
+#include <kapplication.h>
+#include <kstdguiitem.h>
+
+extern PrintOptions printops;
+extern EvaluationOptions evalops;
+extern tree_struct function_cats;
+
+QalculateEditFunctionDialog::QalculateEditFunctionDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Function"), Ok | Cancel | Help, Ok, false) {
+
+ names_edit_dialog = NULL;
+ subfunctions_edit_dialog = NULL;
+ edited_function = NULL;
+ argument_edit_dialog = NULL;
+
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ tabs = new QTabWidget(this);
+#else
+ tabs = new KTabWidget(this);
+#endif
+ setMainWidget(tabs);
+ QWidget *page1 = new QWidget(this);
+ QWidget *page2 = new QWidget(this);
+ tabs->addTab(page1, i18n("General"));
+ tabs->addTab(page2, i18n("Function"));
+ QGridLayout *grid = new QGridLayout(page1, 1, 1, spacingHint());
+ QVBoxLayout *vbox = new QVBoxLayout(page2, spacingHint());
+ grid->addWidget(new QLabel(i18n("Name:"), page1), 0, 0);
+ nameEdit = new KLineEdit(page1);
+ grid->addWidget(nameEdit, 0, 1);
+ QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
+ namesLabel = new QLabel(page1);
+ namesLabel->setAlignment(Qt::AlignRight);
+ namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ hbox->addWidget(namesLabel);
+ namesButton = new QPushButton(i18n("Names Details"), page1);
+ hbox->addWidget(namesButton);
+ grid->addWidget(new QLabel(i18n("Category:"), page1), 2, 0);
+ categoryCombo = new KComboBox(page1);
+ categoryCombo->setMaximumWidth(250);
+ categoryCombo->setEditable(true);
+ grid->addWidget(categoryCombo, 2, 1);
+ grid->addWidget(new QLabel(i18n("Descriptive name:"), page1), 3, 0);
+ titleEdit = new KLineEdit(page1);
+ grid->addWidget(titleEdit, 3, 1);
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 4, 4, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ hideButton = new QCheckBox(i18n("Hide function"), page1);
+ hbox->addWidget(hideButton);
+ grid->addWidget(new QLabel(i18n("Description:"), page1), 5, 0);
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
+ descriptionEdit = new QTextEdit(page1);
+#else
+ descriptionEdit = new KTextEdit(page1);
+#endif
+ descriptionEdit->setTextFormat(QTextEdit::PlainText);
+ grid->addMultiCellWidget(descriptionEdit, 6, 6, 0, 1);
+ vbox->addWidget(new QLabel(i18n("Expression:"), page2));
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
+ expressionEdit = new QTextEdit(page2);
+#else
+ expressionEdit = new KTextEdit(page2);
+#endif
+ expressionEdit->setTextFormat(QTextEdit::PlainText);
+ vbox->addWidget(expressionEdit);
+ hbox = new QHBoxLayout(vbox, spacingHint());
+ hbox->addWidget(new QLabel(i18n("Condition:"), page2));
+ conditionEdit = new KLineEdit(page2);
+ hbox->addWidget(conditionEdit);
+ hbox = new QHBoxLayout(vbox, spacingHint());
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ subFunctionsButton = new QPushButton(i18n("Sub-Functions"), page2);
+ hbox->addWidget(subFunctionsButton);
+ vbox->addWidget(new QLabel(i18n("Arguments:"), page2));
+ argumentsView = new KListView(page2);
+ argumentsView->addColumn(i18n("Name"));
+ argumentsView->addColumn(i18n("Type"));
+ argumentsView->setSorting(-1);
+ argumentsView->setRootIsDecorated(false);
+ argumentsView->setItemsRenameable(true);
+ argumentsView->setItemsMovable(false);
+ vbox->addWidget(argumentsView);
+ hbox = new QHBoxLayout(vbox, spacingHint());
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ newArgumentButton = new QPushButton(i18n("New"), page2);
+ hbox->addWidget(newArgumentButton);
+ editArgumentButton = new QPushButton(i18n("Edit"), page2);
+ hbox->addWidget(editArgumentButton);
+ deleteArgumentButton = new QPushButton(i18n("Delete"), page2);
+ hbox->addWidget(deleteArgumentButton);
+
+ connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
+ connect(subFunctionsButton, SIGNAL(clicked()), this, SLOT(editSubFunctions()));
+ connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
+ connect(newArgumentButton, SIGNAL(clicked()), this, SLOT(newArgument()));
+ connect(editArgumentButton, SIGNAL(clicked()), this, SLOT(editArgument()));
+ connect(deleteArgumentButton, SIGNAL(clicked()), this, SLOT(deleteArgument()));
+ connect(argumentsView, SIGNAL(itemRenamed(QListViewItem*, const QString&, int)), this, SLOT(argumentRenamed(QListViewItem*, const QString&, int)));
+ connect(argumentsView, SIGNAL(selectionChanged()), this, SLOT(argumentSelectionChanged()));
+
+}
+
+QalculateEditFunctionDialog::~QalculateEditFunctionDialog() {}
+
+
+void QalculateEditFunctionDialog::slotHelp() {
+ KApplication::kApplication()->invokeHelp("qalculate-function-creation");
+}
+
+void QalculateEditFunctionDialog::argumentSelectionChanged() {
+ QListViewItem *i = argumentsView->selectedItem();
+ if(i == NULL || (edited_function && edited_function->isBuiltin()) || argumentsItems[i]->type() > ARGUMENT_TYPE_ANGLE) {
+ editArgumentButton->setEnabled(false);
+ deleteArgumentButton->setEnabled(false);
+ } else {
+ editArgumentButton->setEnabled(true);
+ deleteArgumentButton->setEnabled(true);
+ }
+}
+void QalculateEditFunctionDialog::argumentRenamed(QListViewItem *i, const QString &str, int col) {
+ if(!i || col != 0) return;
+ if(col == 0) {
+ if(!argumentsItemsEdited[i]) {
+ argumentsItems[i] = argumentsItems[i]->copy();
+ argumentsItemsEdited[i] = true;
+ }
+ argumentsItems[i]->setName(str.ascii());
+ }
+}
+
+void QalculateEditFunctionDialog::slotOk() {
+
+ string str = nameEdit->text().ascii();
+ remove_blank_ends(str);
+ string str2 = CALCULATOR->unlocalizeExpression(expressionEdit->text().ascii(), evalops.parse_options);
+ remove_blank_ends(str2);
+ gsub("\n", " ", str2);
+ if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
+ //no name -- open dialog again
+ tabs->setCurrentPage(0);
+ nameEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty name field"));
+ return;
+ }
+ if(!(edited_function && edited_function->isBuiltin()) && str2.empty()) {
+ //no expression/relation -- open dialog again
+ tabs->setCurrentPage(1);
+ expressionEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty expression field"));
+ return;
+ }
+ //function with the same name exists -- overwrite or open dialog again
+ if((!edited_function || !edited_function->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->functionNameTaken(str, edited_function) && KMessageBox::questionYesNo(this, i18n("A function with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
+ tabs->setCurrentPage(0);
+ nameEdit->setFocus();
+ return;
+ }
+
+ MathFunction *f = edited_function;
+
+ bool add_func = false;
+ if(f) {
+ f->setLocal(true);
+ //edited an existing function
+ f->setCategory(categoryCombo->lineEdit()->text().ascii());
+ f->setTitle(titleEdit->text().ascii());
+ f->setDescription(descriptionEdit->text().ascii());
+ } else {
+ //new function
+ f = new UserFunction(categoryCombo->lineEdit()->text().ascii(), "", "", true, -1, titleEdit->text().ascii(), descriptionEdit->text().ascii());
+ add_func = true;
+ }
+ f->setCondition(CALCULATOR->unlocalizeExpression(conditionEdit->text().ascii(), evalops.parse_options));
+ size_t index = 1;
+ QListViewItemIterator it(argumentsView);
+ while(it.current()) {
+ if(argumentsItemsEdited[it.current()]) {
+ if(f->isBuiltin() && f->getArgumentDefinition(index)) {
+ f->getArgumentDefinition(index)->setName(argumentsItems[it.current()]->name());
+ delete argumentsItems[it.current()];
+ } else {
+ f->setArgumentDefinition(index, argumentsItems[it.current()]);
+ }
+ }
+ ++it;
+ index++;
+ }
+ if(!f->isBuiltin()) {
+ for(; index <= f->lastArgumentDefinitionIndex(); index++) {
+ f->setArgumentDefinition(index, NULL);
+ }
+ }
+ argumentsItemsEdited.clear();
+ argumentsItems.clear();
+ f->setHidden(hideButton->isChecked());
+ if(!f->isBuiltin()) {
+ if(names_edit_dialog) {
+ names_edit_dialog->saveNames(f, str.c_str());
+ } else {
+ if(f->countNames() == 0) {
+ ExpressionName ename(str);
+ ename.reference = true;
+ f->setName(ename, 1);
+ } else {
+ f->setName(str, 1);
+ }
+ }
+ if(subfunctions_edit_dialog) {
+ subfunctions_edit_dialog->saveSubFunctions((UserFunction*) f);
+ }
+ ((UserFunction*) f)->setFormula(str2);
+ }
+ if(add_func) {
+ CALCULATOR->addFunction(f);
+ }
+ edited_function = f;
+
+ accept();
+
+}
+
+MathFunction *QalculateEditFunctionDialog::editFunction(QString category, MathFunction *f) {
+
+ nameEdit->setFocus();
+
+ tabs->setCurrentPage(0);
+ if(names_edit_dialog) {
+ delete names_edit_dialog;
+ names_edit_dialog = NULL;
+ }
+ if(subfunctions_edit_dialog) {
+ delete subfunctions_edit_dialog;
+ subfunctions_edit_dialog = NULL;
+ }
+ edited_function = f;
+ if(f) {
+ if(f->isLocal())
+ setCaption(i18n("Edit Function"));
+ else
+ setCaption(i18n("Edit Function (global)"));
+ } else {
+ setCaption(i18n("New Function"));
+ }
+
+ QString catstr;
+ categoryCombo->clear();
+ tree_struct *item, *item2;
+ function_cats.it = function_cats.items.begin();
+ if(function_cats.it != function_cats.items.end()) {
+ item = &*function_cats.it;
+ ++function_cats.it;
+ item->it = item->items.begin();
+ } else {
+ item = NULL;
+ }
+
+ catstr = "";
+ while(item) {
+ if(!catstr.isEmpty()) catstr += "/";
+ catstr += item->item.c_str();
+ categoryCombo->insertItem(catstr);
+ while(item && item->it == item->items.end()) {
+ int str_i = catstr.findRev("/");
+ if(str_i < 0) {
+ catstr = "";
+ } else {
+ catstr.truncate(str_i);
+ }
+ item = item->parent;
+ }
+ if(item) {
+ item2 = &*item->it;
+ ++item->it;
+ item = item2;
+ item->it = item->items.begin();
+ }
+ }
+
+ //clear entries
+ nameEdit->clear();
+ namesLabel->clear();
+ conditionEdit->clear();
+ nameEdit->setReadOnly(f && f->isBuiltin());
+ expressionEdit->setEnabled(!f || !f->isBuiltin());
+ categoryCombo->lineEdit()->setText(category);
+ titleEdit->clear();
+ descriptionEdit->clear();
+ expressionEdit->clear();
+ hideButton->setChecked(false);
+ actionButton(Ok)->setEnabled(true);
+ subFunctionsButton->setEnabled(!f || !f->isBuiltin());
+ conditionEdit->setReadOnly(f && f->isBuiltin());
+ newArgumentButton->setEnabled(!f || !f->isBuiltin());
+ if(f) {
+ //fill in original paramaters
+ set_name_label_and_entry(f, nameEdit, namesLabel);
+ if(!f->isBuiltin()) {
+ expressionEdit->setText(CALCULATOR->localizeExpression(((UserFunction*) f)->formula()).c_str());
+ }
+ categoryCombo->lineEdit()->setText(f->category().c_str());
+ titleEdit->setText(f->title(false).c_str());
+ conditionEdit->setText(CALCULATOR->localizeExpression(f->condition()).c_str());
+ hideButton->setChecked(f->isHidden());
+ descriptionEdit->setText(f->description().c_str());
+
+ }
+ argumentsView->clear();
+ argumentsItems.clear();
+ argumentsItemsEdited.clear();
+ editArgumentButton->setEnabled(false);
+ deleteArgumentButton->setEnabled(false);
+ Argument defarg;
+ if(f) {
+ Argument *arg;
+ int args = f->maxargs();
+ if(args < 0) {
+ args = f->minargs() + 1;
+ }
+ QString str, str2;
+ QListViewItem *i_prev = NULL;
+ for(int i = 1; i <= args; i++) {
+ arg = f->getArgumentDefinition(i);
+ if(arg) {
+ arg = arg->copy();
+ str = arg->printlong().c_str();
+ str2 = arg->name().c_str();
+ } else {
+ arg = &defarg;
+ str = defarg.printlong().c_str();
+ str2 = "";
+ }
+ QListViewItem *i = new KListViewItem(argumentsView, i_prev, str2, str);
+ i_prev = i;
+ argumentsItems[i] = arg;
+ argumentsItemsEdited[i] = false;
+ }
+ }
+ argumentsView->setResizeMode(KListView::AllColumns);
+
+ if(exec() == QDialog::Accepted) {
+ f = edited_function;
+ edited_function = NULL;
+ return f;
+ }
+ QListViewItemIterator it(argumentsView);
+ while(it.current()) {
+ if(argumentsItemsEdited[it.current()]) {
+ delete argumentsItems[it.current()];
+ }
+ ++it;
+ }
+ argumentsItemsEdited.clear();
+ argumentsItems.clear();
+ edited_function = NULL;
+ return NULL;
+}
+
+void QalculateEditFunctionDialog::editNames() {
+ if(!names_edit_dialog) {
+ names_edit_dialog = new QalculateEditNamesDialog(TYPE_FUNCTION, this);
+ names_edit_dialog->setNames(edited_function, nameEdit->text(), false);
+ } else {
+ names_edit_dialog->setNames(edited_function, nameEdit->text(), true);
+ }
+ names_edit_dialog->exec();
+ names_edit_dialog->setNamesLE(nameEdit, namesLabel);
+}
+void QalculateEditFunctionDialog::newArgument() {
+ if(!argument_edit_dialog) {
+ argument_edit_dialog = new QalculateEditArgumentDialog(this);
+ }
+ Argument *arg = argument_edit_dialog->editArgument();
+ if(arg) {
+ QListViewItem *i = new KListViewItem(argumentsView, argumentsView->lastChild(), arg->name().c_str(), arg->printlong().c_str());
+ argumentsItems[i] = arg;
+ argumentsItemsEdited[i] = true;
+ }
+}
+void QalculateEditFunctionDialog::editArgument() {
+ QListViewItem *i = argumentsView->selectedItem();
+ if(i == NULL) return;
+ if(!argument_edit_dialog) {
+ argument_edit_dialog = new QalculateEditArgumentDialog(this);
+ }
+ Argument *arg = argument_edit_dialog->editArgument(argumentsItems[i]);
+ if(arg) {
+ if(argumentsItemsEdited[i]) {
+ delete argumentsItems[i];
+ }
+ argumentsItemsEdited[i] = true;
+ argumentsItems[i] = arg;
+ i->setText(0, arg->name().c_str());
+ i->setText(1, arg->printlong().c_str());
+ }
+}
+void QalculateEditFunctionDialog::deleteArgument() {
+ QListViewItem *i = argumentsView->selectedItem();
+ if(i == NULL) return;
+ if(argumentsItemsEdited[i]) {
+ delete argumentsItems[i];
+ }
+ argumentsItemsEdited.erase(i);
+ argumentsItems.erase(i);
+ argumentsView->removeItem(i);
+}
+void QalculateEditFunctionDialog::editSubFunctions() {
+ if(edited_function && edited_function->isBuiltin()) return;
+ if(!subfunctions_edit_dialog) {
+ subfunctions_edit_dialog = new QalculateEditSubFunctionsDialog(this);
+ subfunctions_edit_dialog->setSubFunctions((UserFunction*) edited_function, false);
+ } else {
+ subfunctions_edit_dialog->setSubFunctions((UserFunction*) edited_function, true);
+ }
+ subfunctions_edit_dialog->exec();
+}
+
+void QalculateEditFunctionDialog::nameChanged(const QString &name) {
+ if(name.isNull()) return;
+ if(!CALCULATOR->functionNameIsValid(name.ascii())) {
+ nameEdit->blockSignals(true);
+ nameEdit->setText(CALCULATOR->convertToValidFunctionName(name.ascii()).c_str());
+ nameEdit->blockSignals(false);
+ }
+}
+
+QalculateEditSubFunctionsDialog::QalculateEditSubFunctionsDialog(QWidget *parent, const char *name) : KDialog(parent, name, true) {
+
+ setCaption(i18n("Sub-Functions"));
+
+ QVBoxLayout *layout = new QVBoxLayout(this, marginHint(), spacingHint());
+
+ subFunctionsView = new KListView(this);
+ subFunctionsView->addColumn(i18n("Reference"));
+ subFunctionsView->addColumn(i18n("Expression"));
+ subFunctionsView->addColumn(i18n("Precalculate"));
+ subFunctionsView->setSorting(-1);
+ subFunctionsView->setItemsRenameable(true);
+ subFunctionsView->setRenameable(0, false);
+ subFunctionsView->setRenameable(1, true);
+ subFunctionsView->setItemsMovable(false);
+ layout->addWidget(subFunctionsView);
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout(layout, spacingHint());
+ newButton = new QPushButton(i18n("New"), this);
+ buttonLayout->addWidget(newButton);
+ deleteButton = new QPushButton(i18n("Delete"), this);
+ deleteButton->setEnabled(false);
+ buttonLayout->addWidget(deleteButton);
+ buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ buttonClose = new KPushButton(KStdGuiItem::close(), this);
+ buttonClose->setAutoDefault(true);
+ buttonClose->setDefault(true);
+ buttonLayout->addWidget(buttonClose);
+
+ connect(subFunctionsView, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
+ connect(buttonClose, SIGNAL(clicked()), this, SLOT(accept()));
+ connect(newButton, SIGNAL(clicked()), this, SLOT(newSubFunction()));
+ connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteSubFunction()));
+ connect(subFunctionsView, SIGNAL(clicked(QListViewItem*, const QPoint&, int)), this, SLOT(itemClicked(QListViewItem*, const QPoint&, int)));
+}
+
+QalculateEditSubFunctionsDialog::~QalculateEditSubFunctionsDialog() {}
+
+void QalculateEditSubFunctionsDialog::newSubFunction() {
+ ExpressionName name;
+ QString str = "\\";
+ str += QString::number(subFunctionsView->childCount() + 1);
+ QListViewItem *i = new KListViewItem(subFunctionsView, subFunctionsView->lastChild(), str, "", i18n("Yes"));
+ subFunctionsView->setSelected(i, true);
+ qApp->processEvents();
+ subFunctionsView->rename(i, 1);
+}
+
+void QalculateEditSubFunctionsDialog::setSubFunctions(UserFunction *f, bool edited) {
+ if(!edited) {
+ deleteButton->setEnabled(false);
+ subFunctionsView->clear();
+ }
+ if(!edited && f && f->countSubfunctions() > 0) {
+ QListViewItem *i_prev = NULL;
+ for(size_t index = 1; index <= f->countSubfunctions(); index++) {
+ QListViewItem *i = new KListViewItem(subFunctionsView, i_prev);
+ i_prev = i;
+ QString str = "\\";
+ str += QString::number(index);
+ i->setText(0, str);
+ i->setText(1, f->getSubfunction(index).c_str());
+ if(f->subfunctionPrecalculated(index)) i->setText(2, i18n("Yes"));
+ else i->setText(2, i18n("No"));
+ }
+ }
+}
+void QalculateEditSubFunctionsDialog::saveSubFunctions(UserFunction *f) {
+ f->clearSubfunctions();
+ QListViewItemIterator it(subFunctionsView);
+ while(it.current()) {
+ f->addSubfunction(it.current()->text(1).ascii(), it.current()->text(2) == i18n("Yes"));
+ ++it;
+ }
+}
+bool QalculateEditSubFunctionsDialog::isEmpty() {
+ return subFunctionsView->childCount() <= 0;
+}
+
+void QalculateEditSubFunctionsDialog::deleteSubFunction() {
+ subFunctionsView->removeItem(subFunctionsView->selectedItem());
+ QListViewItemIterator it(subFunctionsView);
+ int index = 1;
+ while(it.current()) {
+ QString str = "\\";
+ str += QString::number(index);
+ it.current()->setText(0, str);
+ ++it;
+ index++;
+ }
+}
+
+void QalculateEditSubFunctionsDialog::itemClicked(QListViewItem *i, const QPoint &, int c) {
+ if(i && c == 2) {
+ if(i->text(c) == i18n("Yes"))
+ i->setText(c, i18n("No"));
+ else
+ i->setText(c, i18n("Yes"));
+ }
+}
+
+void QalculateEditSubFunctionsDialog::selectionChanged() {
+ deleteButton->setEnabled(subFunctionsView->selectedItem() != NULL);
+}
+
+QalculateEditArgumentDialog::QalculateEditArgumentDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Argument"), Ok | Cancel, Ok, true) {
+
+ setMainWidget(new QWidget(this));
+ QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
+ grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 0, 0);
+ nameEdit = new KLineEdit(mainWidget());
+ grid->addWidget(nameEdit, 0, 1);
+ grid->addWidget(new QLabel(i18n("Type:"), mainWidget()), 1, 0);
+ typeCombo = new KComboBox(mainWidget());
+ typeCombo->setEditable(false);
+ typeCombo->insertItem(i18n("Free"));
+ typeCombo->insertItem(i18n("Number"));
+ typeCombo->insertItem(i18n("Integer"));
+ typeCombo->insertItem(i18n("Symbol"));
+ typeCombo->insertItem(i18n("Text"));
+ typeCombo->insertItem(i18n("Date"));
+ typeCombo->insertItem(i18n("Vector"));
+ typeCombo->insertItem(i18n("Matrix"));
+ typeCombo->insertItem(i18n("Boolean"));
+ typeCombo->insertItem(i18n("Object"));
+ typeCombo->insertItem(i18n("Function"));
+ typeCombo->insertItem(i18n("Unit"));
+ typeCombo->insertItem(i18n("Variable"));
+ typeCombo->insertItem(i18n("File"));
+ typeCombo->insertItem(i18n("Angle"));
+ grid->addWidget(typeCombo, 1, 1);
+ testButton = new QCheckBox(i18n("Enable rules and type test"), mainWidget());
+ grid->addMultiCellWidget(testButton, 2, 2, 0, 1);
+ conditionButton = new QCheckBox(i18n("Custom condition:"), mainWidget());
+ grid->addWidget(conditionButton, 3, 0);
+ conditionEdit = new KLineEdit(mainWidget());
+ grid->addWidget(conditionEdit, 3, 1);
+ matrixButton = new QCheckBox(i18n("Allow matrix"), mainWidget());
+ grid->addMultiCellWidget(matrixButton, 4, 4, 0, 1);
+ zeroButton = new QCheckBox(i18n("Forbid zero"), mainWidget());
+ grid->addMultiCellWidget(zeroButton, 5, 5, 0, 1);
+ complexButton = new QCheckBox(i18n("Allow complex"), mainWidget());
+ grid->addMultiCellWidget(complexButton, 6, 6, 0, 1);
+ minButton = new QCheckBox(i18n("Min:"), mainWidget());
+ grid->addWidget(minButton, 7, 0);
+ minEdit = new KLineEdit(mainWidget());
+ grid->addWidget(minEdit, 7, 1);
+ QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 8, 8, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ minIncludeEqualsButton = new QCheckBox(i18n("Include equals"), mainWidget());
+ hbox->addWidget(minIncludeEqualsButton);
+ maxButton = new QCheckBox(i18n("Max:"), mainWidget());
+ grid->addWidget(maxButton, 9, 0);
+ maxEdit = new KLineEdit(mainWidget());
+ grid->addWidget(maxEdit, 9, 1);
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 10, 10, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ maxIncludeEqualsButton = new QCheckBox(i18n("Include equals"), mainWidget());
+ hbox->addWidget(maxIncludeEqualsButton);
+
+ connect(conditionButton, SIGNAL(toggled(bool)), conditionEdit, SLOT(setEnabled(bool)));
+ connect(minButton, SIGNAL(toggled(bool)), this, SLOT(minEnabled(bool)));
+ connect(maxButton, SIGNAL(toggled(bool)), this, SLOT(maxEnabled(bool)));
+ connect(typeCombo, SIGNAL(activated(int)), this, SLOT(typeChanged(int)));
+
+}
+
+QalculateEditArgumentDialog::~QalculateEditArgumentDialog() {}
+
+void QalculateEditArgumentDialog::typeChanged(int i) {
+ maxButton->setEnabled(i == 1 || i == 2);
+ maxEdit->setEnabled(maxButton->isChecked() && (i == 1 || i == 2));
+ maxIncludeEqualsButton->setEnabled(maxButton->isChecked() && i == 1);
+ maxIncludeEqualsButton->setChecked(i == 1 || i == 2);
+ minButton->setEnabled(i == 1 || i == 2);
+ minEdit->setEnabled(maxButton->isChecked() && (i == 1 || i == 2));
+ minIncludeEqualsButton->setEnabled(minButton->isChecked() && i == 1);
+ minIncludeEqualsButton->setChecked(i == 1 || i == 2);
+ matrixButton->setEnabled(i != 7 && i != 0);
+ matrixButton->setChecked(i == 7 || i == 0);
+ complexButton->setEnabled(i == 1);
+ complexButton->setChecked(i == 1);
+}
+void QalculateEditArgumentDialog::maxEnabled(bool b) {
+ maxEdit->setEnabled(b);
+ if(typeCombo->currentItem() == 2) {
+ maxIncludeEqualsButton->setEnabled(b);
+ }
+}
+void QalculateEditArgumentDialog::minEnabled(bool b) {
+ minEdit->setEnabled(b);
+ if(typeCombo->currentItem() == 2) {
+ minIncludeEqualsButton->setEnabled(b);
+ }
+}
+
+Argument *QalculateEditArgumentDialog::editArgument(Argument *arg) {
+
+ if(arg) {
+ setCaption(i18n("Edit Argument"));
+ } else {
+ setCaption(i18n("New Argument"));
+ }
+
+ nameEdit->setFocus();
+
+ typeCombo->setCurrentItem(0);
+ conditionEdit->clear();
+ conditionButton->setChecked(false);
+ nameEdit->clear();
+ maxEdit->setText("0");
+ minEdit->setText("0");
+ testButton->setChecked(true);
+ zeroButton->setChecked(false);
+ matrixButton->setChecked(false);
+ complexButton->setChecked(false);
+ PrintOptions po;
+ po.number_fraction_format = FRACTION_DECIMAL_EXACT;
+ if(arg) {
+ switch(arg->type()) {
+ case ARGUMENT_TYPE_NUMBER: {
+ typeCombo->setCurrentItem(1);
+ NumberArgument *farg = (NumberArgument*) arg;
+ minButton->setChecked(farg->min() != NULL);
+ minIncludeEqualsButton->setChecked(farg->includeEqualsMin());
+ if(farg->min()) minEdit->setText(farg->min()->print(po).c_str());
+ maxButton->setChecked(farg->max() != NULL);
+ maxIncludeEqualsButton->setChecked(farg->includeEqualsMax());
+ if(farg->max()) maxEdit->setText(farg->max()->print(po).c_str());
+ complexButton->setChecked(farg->complexAllowed());
+ break;
+ }
+ case ARGUMENT_TYPE_INTEGER: {
+ typeCombo->setCurrentItem(2);
+ IntegerArgument *iarg = (IntegerArgument*) arg;
+ minButton->setChecked(iarg->min() != NULL);
+ if(iarg->min()) minEdit->setText(iarg->min()->print(po).c_str());
+ maxButton->setChecked(iarg->max() != NULL);
+ if(iarg->max()) maxEdit->setText(iarg->max()->print(po).c_str());
+ break;
+ }
+ case ARGUMENT_TYPE_TEXT: {typeCombo->setCurrentItem(4); break;}
+ case ARGUMENT_TYPE_SYMBOLIC: {typeCombo->setCurrentItem(3); break;}
+ case ARGUMENT_TYPE_DATE: {typeCombo->setCurrentItem(5); break;}
+ case ARGUMENT_TYPE_VECTOR: {typeCombo->setCurrentItem(6); break;}
+ case ARGUMENT_TYPE_MATRIX: {typeCombo->setCurrentItem(7); break;}
+ case ARGUMENT_TYPE_EXPRESSION_ITEM: {typeCombo->setCurrentItem(9); break;}
+ case ARGUMENT_TYPE_FUNCTION: {typeCombo->setCurrentItem(10); break;}
+ case ARGUMENT_TYPE_UNIT: {typeCombo->setCurrentItem(11); break;}
+ case ARGUMENT_TYPE_VARIABLE: {typeCombo->setCurrentItem(12); break;}
+ case ARGUMENT_TYPE_FILE: {typeCombo->setCurrentItem(13); break;}
+ case ARGUMENT_TYPE_BOOLEAN: {typeCombo->setCurrentItem(8); break;}
+ case ARGUMENT_TYPE_ANGLE: {typeCombo->setCurrentItem(14); break;}
+ }
+ nameEdit->setText(arg->name().c_str());
+ matrixButton->setChecked(arg->matrixAllowed());
+ zeroButton->setChecked(arg->zeroForbidden());
+ testButton->setChecked(arg->tests());
+ if(!arg->getCustomCondition().empty()) {
+ conditionButton->setChecked(true);
+ conditionEdit->setText(arg->getCustomCondition().c_str());
+ }
+ }
+ typeChanged(typeCombo->currentItem());
+
+ if(exec() == QDialog::Accepted) {
+ switch(typeCombo->currentItem()) {
+ case 1: {
+ arg = new NumberArgument();
+ if(minButton->isChecked()) {
+ Number nr(minEdit->text().ascii());
+ ((NumberArgument*) arg)->setMin(&nr);
+ }
+ ((NumberArgument*) arg)->setIncludeEqualsMin(minIncludeEqualsButton->isChecked());
+ if(maxButton->isChecked()) {
+ Number nr(maxEdit->text().ascii());
+ ((NumberArgument*) arg)->setMax(&nr);
+ }
+ ((NumberArgument*) arg)->setIncludeEqualsMax(maxIncludeEqualsButton->isChecked());
+ break;
+ }
+ case 2: {
+ arg = new IntegerArgument();
+ if(minButton->isChecked()) {
+ Number nr(minEdit->text().ascii());
+ ((IntegerArgument*) arg)->setMin(&nr);
+ }
+ if(maxButton->isChecked()) {
+ Number nr(maxEdit->text().ascii());
+ ((IntegerArgument*) arg)->setMax(&nr);
+ }
+ break;
+ }
+ case 3: {arg = new SymbolicArgument(); break;}
+ case 4: {arg = new TextArgument(); break;}
+ case 5: {arg = new DateArgument(); break;}
+ case 6: {arg = new VectorArgument(); break;}
+ case 7: {arg = new MatrixArgument(); break;}
+ case 8: {arg = new BooleanArgument(); break;}
+ case 9: {arg = new ExpressionItemArgument(); break;}
+ case 10: {arg = new FunctionArgument(); break;}
+ case 11: {arg = new UnitArgument(); break;}
+ case 12: {arg = new VariableArgument(); break;}
+ case 13: {arg = new FileArgument(); break;}
+ case 14: {arg = new AngleArgument(); break;}
+ default: {arg = new Argument(); break;}
+ }
+ arg->setName(nameEdit->text().ascii());
+ arg->setZeroForbidden(zeroButton->isChecked());
+ arg->setTests(testButton->isChecked());
+ if(conditionButton->isChecked()) {
+ arg->setCustomCondition(conditionEdit->text().ascii());
+ } else {
+ arg->setCustomCondition("");
+ }
+ if(arg->type() != ARGUMENT_TYPE_FREE && arg->type() != ARGUMENT_TYPE_MATRIX) arg->setMatrixAllowed(matrixButton->isChecked());
+ return arg;
+ }
+ return NULL;
+
+}
+
+#include "qalculateeditfunctiondialog.moc"
+
diff --git a/src/qalculateeditfunctiondialog.h b/src/qalculateeditfunctiondialog.h
new file mode 100644
index 0000000..ecd322d
--- /dev/null
+++ b/src/qalculateeditfunctiondialog.h
@@ -0,0 +1,140 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEEDITFUNCTIONDIALOG_H
+#define QALCULATEEDITFUNCTIONDIALOG_H
+
+#include <kdialogbase.h>
+#include <qmap.h>
+
+class QLabel;
+class KComboBox;
+class KLineEdit;
+class QCheckBox;
+class QPushButton;
+class MathStructure;
+class QalculateEditNamesDialog;
+class QalculateEditSubFunctionsDialog;
+class QalculateEditArgumentDialog;
+class MathFunction;
+class KListView;
+class QTextEdit;
+class Argument;
+class QTabWidget;
+class UserFunction;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateEditFunctionDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateEditFunctionDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateEditFunctionDialog();
+
+ MathFunction *editFunction(QString category = QString::null, MathFunction *f = NULL);
+
+ QalculateEditNamesDialog *names_edit_dialog;
+ QalculateEditSubFunctionsDialog *subfunctions_edit_dialog;
+ QalculateEditArgumentDialog *argument_edit_dialog;
+ MathFunction *edited_function;
+ KComboBox *categoryCombo;
+ KLineEdit *conditionEdit, *nameEdit, *titleEdit;
+ QLabel *namesLabel;
+ QCheckBox *hideButton;
+ KListView *argumentsView;
+ QTextEdit *descriptionEdit, *expressionEdit;
+ QPushButton *namesButton, *subFunctionsButton, *newArgumentButton, *editArgumentButton, *deleteArgumentButton;
+ QTabWidget *tabs;
+ QMap<QListViewItem*, Argument*> argumentsItems;
+ QMap<QListViewItem*, bool> argumentsItemsEdited;
+
+public slots:
+
+ void argumentSelectionChanged();
+ void argumentRenamed(QListViewItem*, const QString&, int);
+ void editNames();
+ void newArgument();
+ void editArgument();
+ void deleteArgument();
+ void editSubFunctions();
+ void nameChanged(const QString&);
+
+protected slots:
+
+ void slotHelp();
+ void slotOk();
+
+};
+
+class QalculateEditSubFunctionsDialog : public KDialog {
+
+ Q_OBJECT
+
+public:
+
+ QalculateEditSubFunctionsDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateEditSubFunctionsDialog();
+
+ void saveSubFunctions(UserFunction *f);
+ void setSubFunctions(UserFunction *f = NULL, bool edited = false);
+ bool isEmpty();
+
+ KListView* subFunctionsView;
+ QPushButton* newButton;
+ QPushButton* deleteButton;
+ QPushButton* buttonClose;
+
+public slots:
+
+ void itemClicked(QListViewItem*, const QPoint&, int);
+ void newSubFunction();
+ void deleteSubFunction();
+ void selectionChanged();
+
+};
+
+class QalculateEditArgumentDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateEditArgumentDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateEditArgumentDialog();
+
+ Argument *editArgument(Argument *arg = NULL);
+
+ KComboBox *typeCombo;
+ KLineEdit *nameEdit, *conditionEdit, *maxEdit, *minEdit;
+ QCheckBox *conditionButton, *matrixButton, *zeroButton, *complexButton, *maxButton, *minButton, *maxIncludeEqualsButton, *minIncludeEqualsButton, *testButton;
+
+public slots:
+
+ void maxEnabled(bool);
+ void minEnabled(bool);
+ void typeChanged(int);
+
+};
+
+
+#endif
diff --git a/src/qalculateeditmatrixvectordialog.cpp b/src/qalculateeditmatrixvectordialog.cpp
new file mode 100644
index 0000000..1dccb03
--- /dev/null
+++ b/src/qalculateeditmatrixvectordialog.cpp
@@ -0,0 +1,491 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateeditmatrixvectordialog.h"
+#include "qalculate_kde_utils.h"
+#include "qalculateeditnamesdialog.h"
+
+#include <qgrid.h>
+#include <klineedit.h>
+#include <qpushbutton.h>
+#include <kcombobox.h>
+#include <qlabel.h>
+#include <klocale.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qcheckbox.h>
+#include <kmessagebox.h>
+#include <qspinbox.h>
+#include <qlayout.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <qtable.h>
+#include <kapplication.h>
+
+extern PrintOptions printops;
+extern EvaluationOptions evalops;
+extern tree_struct variable_cats;
+
+class QalculateEditMatrixVectorTableItem : public QTableItem {
+
+ public:
+
+ QalculateEditMatrixVectorTableItem(QTable *table);
+ QalculateEditMatrixVectorTableItem(QTable *table, const QString & text);
+
+ int alignment() const;
+
+};
+
+class QalculateEditMatrixTable : public QTable {
+
+ public:
+
+ QalculateEditMatrixTable(QWidget *parent = 0, const char *name = 0) : QTable(parent, name) {}
+ QalculateEditMatrixTable(int numRows, int numCols, QWidget *parent = 0, const char *name = 0) : QTable(numRows, numCols, parent, name) {}
+
+ QWidget *beginEdit(int row, int col, bool replace) {
+ QWidget *w = QTable::beginEdit(row, col, replace);
+ ((QLineEdit*) w)->selectAll();
+ return w;
+ }
+
+};
+
+QalculateEditMatrixVectorDialog::QalculateEditMatrixVectorDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Variable"), Ok | Cancel | Help, Ok, true) {
+
+ names_edit_dialog = NULL;
+ edited_variable = NULL;
+
+ setMainWidget(new QWidget(this));
+ QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
+ grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 0, 0);
+ nameEdit = new KLineEdit(mainWidget());
+ grid->addWidget(nameEdit, 0, 1);
+ QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
+ namesLabel = new QLabel(mainWidget());
+ namesLabel->setAlignment(Qt::AlignRight);
+ namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ hbox->addWidget(namesLabel);
+ namesButton = new QPushButton(i18n("Names Details"), mainWidget());
+ hbox->addWidget(namesButton);
+ grid->addWidget(new QLabel(i18n("Category:"), mainWidget()), 2, 0);
+ categoryCombo = new KComboBox(mainWidget());
+ categoryCombo->setEditable(true);
+ grid->addWidget(categoryCombo, 2, 1);
+ grid->addWidget(new QLabel(i18n("Descriptive name:"), mainWidget()), 3, 0);
+ titleEdit = new KLineEdit(mainWidget());
+ grid->addWidget(titleEdit, 3, 1);
+ grid->addWidget(new QLabel(i18n("Rows:"), mainWidget()), 4, 0);
+ rowsBox = new QSpinBox(1, 1000, 1, mainWidget());
+ grid->addWidget(rowsBox, 4, 1);
+ grid->addWidget(new QLabel(i18n("Columns:"), mainWidget()), 5, 0);
+ columnsBox = new QSpinBox(1, 1000, 1, mainWidget());
+ grid->addWidget(columnsBox, 5, 1);
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 6, 6, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ QButtonGroup *group = new QButtonGroup();
+ matrixButton = new QRadioButton(i18n("Matrix"), mainWidget());
+ group->insert(matrixButton, 0);
+ hbox->addWidget(matrixButton);
+ vectorButton = new QRadioButton(i18n("Vector"), mainWidget());
+ group->insert(vectorButton, 1);
+ hbox->addWidget(vectorButton);
+ elementsLabel = new QLabel(i18n("Elements:"), mainWidget());
+ grid->addMultiCellWidget(elementsLabel, 7, 7, 0, 1);
+ elementsTable = new QalculateEditMatrixTable(0, 0, mainWidget());
+ grid->addMultiCellWidget(elementsTable, 8, 8, 0, 1);
+
+ connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
+ connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
+ connect(rowsBox, SIGNAL(valueChanged(int)), this, SLOT(rowsChanged(int)));
+ connect(columnsBox, SIGNAL(valueChanged(int)), this, SLOT(columnsChanged(int)));
+ connect(group, SIGNAL(clicked(int)), this, SLOT(typeChanged(int)));
+
+}
+
+QalculateEditMatrixVectorDialog::~QalculateEditMatrixVectorDialog() {}
+
+void QalculateEditMatrixVectorDialog::slotHelp() {
+ KApplication::kApplication()->invokeHelp("qalculate-vectors-matrices");
+}
+
+void QalculateEditMatrixVectorDialog::typeChanged(int i) {
+ if(i == 0) {
+ elementsLabel->setText(i18n("Elements:"));
+ bool b = true;
+ for(int index_r = elementsTable->numRows() - 1; index_r >= 0 && b; index_r--) {
+ for(int index_c = elementsTable->numCols() - 1; index_c >= 0; index_c--) {
+ if(elementsTable->text(index_r, index_c).isEmpty()) {
+ elementsTable->setText(index_r, index_c, "0");
+ } else {
+ b = false;
+ break;
+ }
+ }
+ }
+ } else {
+ elementsLabel->setText(i18n("Elements (in horizontal order):"));
+ }
+}
+void QalculateEditMatrixVectorDialog::rowsChanged(int i) {
+ int r = elementsTable->numRows();
+ elementsTable->setNumRows(i);
+ bool b = matrixButton->isChecked();
+ for(int index_r = r; index_r < i; index_r++) {
+ for(int index_c = 0; index_c < elementsTable->numCols(); index_c++) {
+ if(b) elementsTable->setItem(index_r, index_c, new QalculateEditMatrixVectorTableItem(elementsTable, "0"));
+ else elementsTable->setItem(index_r, index_c, new QalculateEditMatrixVectorTableItem(elementsTable));
+ }
+ }
+}
+void QalculateEditMatrixVectorDialog::columnsChanged(int i) {
+ int c = elementsTable->numCols();
+ elementsTable->setNumCols(i);
+ bool b = matrixButton->isChecked();
+ for(int index_r = 0; index_r < elementsTable->numRows(); index_r++) {
+ for(int index_c = c; index_c < i; index_c++) {
+ if(b) elementsTable->setItem(index_r, index_c, new QalculateEditMatrixVectorTableItem(elementsTable, "0"));
+ else elementsTable->setItem(index_r, index_c, new QalculateEditMatrixVectorTableItem(elementsTable));
+ }
+ }
+}
+
+KnownVariable *QalculateEditMatrixVectorDialog::newVector(QString category) {
+ return editVariable(category, NULL, NULL, false, true);
+}
+KnownVariable *QalculateEditMatrixVectorDialog::newMatrix(QString category) {
+ return editVariable(category, NULL, NULL, false, false);
+}
+
+void QalculateEditMatrixVectorDialog::slotOk() {
+ string str = nameEdit->text().ascii();
+ remove_blank_ends(str);
+ if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
+ //no name -- open dialog again
+ nameEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty name field"));
+ return;
+ }
+ //variable with the same name exists -- overwrite or open dialog again
+ if((!edited_variable || !edited_variable->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->variableNameTaken(str, edited_variable) && KMessageBox::questionYesNo(this, i18n("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
+ nameEdit->setFocus();
+ return;
+ }
+ KnownVariable *v = edited_variable;
+ if(!v) {
+ //no need to create a new variable when a variable with the same name exists
+ Variable *var = CALCULATOR->getActiveVariable(str);
+ if(var && var->isLocal() && var->isKnown()) v = (KnownVariable*) var;
+ }
+ MathStructure mstruct_new;
+ if(!init_value) {
+ int r = rowsBox->value();
+ int c = columnsBox->value();
+ if(vectorButton->isChecked()) {
+ mstruct_new.clearVector();
+ string str2;
+ for(int index_r = 0; index_r < r; index_r++) {
+ for(int index_c = 0; index_c < c; index_c++) {
+ if(!elementsTable->text(index_r, index_c).isEmpty()) {
+ str2 = elementsTable->text(index_r, index_c).ascii();
+ remove_blank_ends(str2);
+ if(!str2.empty()) {
+ mstruct_new.addChild(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str2, evalops.parse_options)));
+ }
+ }
+ }
+ }
+ } else {
+ mstruct_new.clearMatrix();
+ mstruct_new.resizeMatrix(r, c, m_undefined);
+ for(int index_r = 0; index_r < r; index_r++) {
+ for(int index_c = 0; index_c < c; index_c++) {
+ if(elementsTable->text(index_r, index_c).isEmpty()) mstruct_new.setElement(m_zero, index_r + 1, index_c + 1);
+ else mstruct_new.setElement(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(elementsTable->text(index_r, index_c).ascii(), evalops.parse_options)), index_r + 1, index_c + 1);
+ }
+ }
+ }
+ }
+ bool add_var = false;
+ if(v) {
+ //update existing variable
+ v->setLocal(true);
+ if(!v->isBuiltin()) {
+ if(init_value) {
+ v->set(*init_value);
+ } else {
+ v->set(mstruct_new);
+ }
+ }
+ } else {
+ //new variable
+ if(force_init_value && init_value) {
+ //forced value
+ v = new KnownVariable("", "", *init_value, "", true);
+ } else {
+ v = new KnownVariable("", "", mstruct_new, "", true);
+ }
+ add_var = true;
+ }
+ v->setCategory(categoryCombo->lineEdit()->text().ascii());
+ v->setTitle(titleEdit->text().ascii());
+ if(!v->isBuiltin()) {
+ if(names_edit_dialog) {
+ names_edit_dialog->saveNames(v, str.c_str());
+ } else {
+ if(v->countNames() == 0) {
+ ExpressionName ename(str);
+ ename.reference = true;
+ v->setName(ename, 1);
+ } else {
+ v->setName(str, 1);
+ }
+ }
+ }
+ if(add_var) {
+ CALCULATOR->addVariable(v);
+ }
+ edited_variable = v;
+ accept();
+}
+
+KnownVariable *QalculateEditMatrixVectorDialog::editVariable(QString category, KnownVariable *v, MathStructure *initial_value, bool force_value, bool create_vector) {
+
+ nameEdit->setFocus();
+
+ if((v && !v->get().isVector()) || (initial_value && !initial_value->isVector())) {
+ return NULL;
+ }
+
+ if(names_edit_dialog) {
+ delete names_edit_dialog;
+ names_edit_dialog = NULL;
+ }
+ edited_variable = v;
+
+ if(initial_value) {
+ create_vector = !initial_value->isMatrix();
+ } else if(v) {
+ create_vector = !v->get().isMatrix();
+ }
+ if(create_vector) {
+ vectorButton->setChecked(true);
+ elementsLabel->setText(i18n("Elements (in horizontal order):"));
+ } else {
+ matrixButton->setChecked(true);
+ elementsLabel->setText(i18n("Elements:"));
+ }
+
+ if(create_vector) {
+ if(v) {
+ if(v->isLocal())
+ setCaption(i18n("Edit Vector"));
+ else
+ setCaption(i18n("Edit Vector (global)"));
+ } else {
+ setCaption(i18n("New Vector"));
+ }
+ } else {
+ if(v) {
+ if(v->isLocal())
+ setCaption(i18n("Edit Matrix"));
+ else
+ setCaption(i18n("Edit Matrix (global)"));
+ } else {
+ setCaption(i18n("New Matrix"));
+ }
+ }
+
+ actionButton(Ok)->setEnabled(true);
+
+ namesLabel->setText("");
+
+ //QStringList cats;
+ QString catstr;
+ categoryCombo->clear();
+ tree_struct *item, *item2;
+ variable_cats.it = variable_cats.items.begin();
+ if(variable_cats.it != variable_cats.items.end()) {
+ item = &*variable_cats.it;
+ ++variable_cats.it;
+ item->it = item->items.begin();
+ } else {
+ item = NULL;
+ }
+
+ catstr = "";
+ while(item) {
+ if(!catstr.isEmpty()) catstr += "/";
+ catstr += item->item.c_str();
+ categoryCombo->insertItem(catstr);
+ while(item && item->it == item->items.end()) {
+ int str_i = catstr.findRev("/");
+ if(str_i < 0) {
+ catstr = "";
+ } else {
+ catstr.truncate(str_i);
+ }
+ item = item->parent;
+ }
+ if(item) {
+ item2 = &*item->it;
+ ++item->it;
+ item = item2;
+ item->it = item->items.begin();
+ }
+ }
+
+ int r = 4, c = 4;
+ const MathStructure *old_vctr = NULL;
+ if(v) {
+ if(create_vector) {
+ old_vctr = &v->get();
+ } else {
+ c = v->get().columns();
+ r = v->get().rows();
+ }
+ set_name_label_and_entry(v, nameEdit, namesLabel);
+ nameEdit->setReadOnly(v->isBuiltin());
+ rowsBox->setEnabled(!v->isBuiltin());
+ columnsBox->setEnabled(!v->isBuiltin());
+ matrixButton->setEnabled(!v->isBuiltin());
+ vectorButton->setEnabled(!v->isBuiltin());
+ elementsTable->setReadOnly(v->isBuiltin());
+ categoryCombo->lineEdit()->setText(v->category().c_str());
+ titleEdit->setText(v->title(false).c_str());
+ } else {
+ nameEdit->setReadOnly(false);
+ rowsBox->setEnabled(true);
+ columnsBox->setEnabled(true);
+ matrixButton->setEnabled(true);
+ vectorButton->setEnabled(true);
+ elementsTable->setReadOnly(false);
+
+ //fill in default values
+ nameEdit->setText(CALCULATOR->getName().c_str());
+ namesLabel->setText("");
+ categoryCombo->lineEdit()->setText(category);
+ titleEdit->setText("");
+ if(force_value) {
+ if(create_vector) {
+ old_vctr = initial_value;
+ } else {
+ c = initial_value->columns();
+ r = initial_value->rows();
+ }
+ rowsBox->setEnabled(false);
+ columnsBox->setEnabled(false);
+ matrixButton->setEnabled(false);
+ vectorButton->setEnabled(false);
+ elementsTable->setReadOnly(true);
+ }
+ }
+
+ if(create_vector) {
+ if(old_vctr) {
+ r = old_vctr->countChildren();
+ c = (int) ::sqrt(r) + 4;
+ if(r % c > 0) {
+ r = r / c + 1;
+ } else {
+ r = r / c;
+ }
+ } else {
+ c = 4;
+ r = 4;
+ }
+ }
+
+ rowsBox->setValue(r);
+ columnsBox->setValue(c);
+ elementsTable->setNumRows(r);
+ elementsTable->setNumCols(c);
+
+ int timeout;
+ if(force_value) timeout = 3000 / (r * c);
+ else timeout = 3000;
+ PrintOptions po;
+ po.number_fraction_format = FRACTION_DECIMAL_EXACT;
+ for(int index_r = 0; index_r < r; index_r++) {
+ for(int index_c = 0; index_c < c; index_c++) {
+ if(create_vector) {
+ if(old_vctr && index_r * c + index_c < (int) old_vctr->countChildren()) {
+ elementsTable->setText(index_r, index_c, old_vctr->getChild(index_r * c + index_c + 1)->print(po).c_str());
+ } else {
+ elementsTable->setText(index_r, index_c, "");
+ }
+ } else {
+ if(v) {
+ elementsTable->setText(index_r, index_c, v->get().getElement(index_r + 1, index_c + 1)->print(po).c_str());
+ } else if(initial_value) {
+ elementsTable->setText(index_r, index_c, initial_value->getElement(index_r + 1, index_c + 1)->print(po).c_str());
+ } else {
+ elementsTable->setText(index_r, index_c, "0");
+ }
+ }
+ }
+ }
+
+ init_value = initial_value;
+ force_init_value = force_value;
+
+ if(exec() == QDialog::Accepted) {
+ v = edited_variable;
+ edited_variable = NULL;
+ return v;
+ }
+
+ edited_variable = NULL;
+ return NULL;
+}
+
+void QalculateEditMatrixVectorDialog::editNames() {
+ if(!names_edit_dialog) {
+ names_edit_dialog = new QalculateEditNamesDialog(TYPE_VARIABLE, this);
+ names_edit_dialog->setNames(edited_variable, nameEdit->text(), false);
+ } else {
+ names_edit_dialog->setNames(edited_variable, nameEdit->text(), true);
+ }
+ names_edit_dialog->exec();
+ names_edit_dialog->setNamesLE(nameEdit, namesLabel);
+}
+
+void QalculateEditMatrixVectorDialog::nameChanged(const QString &name) {
+ if(name.isNull()) return;
+ if(!CALCULATOR->variableNameIsValid(name.ascii())) {
+ nameEdit->blockSignals(true);
+ nameEdit->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str());
+ nameEdit->blockSignals(false);
+ }
+}
+
+#if QT_VERSION >= 0x030200
+QalculateEditMatrixVectorTableItem::QalculateEditMatrixVectorTableItem(QTable *table) : QTableItem(table, QTableItem::OnTyping) {}
+#else
+QalculateEditMatrixVectorTableItem::QalculateEditMatrixVectorTableItem(QTable *table) : QTableItem(table, QTableItem::OnTyping, QString::null) {}
+#endif
+QalculateEditMatrixVectorTableItem::QalculateEditMatrixVectorTableItem(QTable *table, const QString & text) : QTableItem(table, QTableItem::OnTyping, text) {}
+
+int QalculateEditMatrixVectorTableItem::alignment() const {return Qt::AlignRight;}
+
+#include "qalculateeditmatrixvectordialog.moc"
+
diff --git a/src/qalculateeditmatrixvectordialog.h b/src/qalculateeditmatrixvectordialog.h
new file mode 100644
index 0000000..6ecd146
--- /dev/null
+++ b/src/qalculateeditmatrixvectordialog.h
@@ -0,0 +1,82 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEEDITMATRIXVECTORDIALOG_H
+#define QALCULATEEDITMATRIXVECTORDIALOG_H
+
+#include <kdialogbase.h>
+
+class QLabel;
+class QSpinBox;
+class QTable;
+class QRadioButton;
+class KComboBox;
+class KLineEdit;
+class QPushButton;
+class MathStructure;
+class QalculateEditNamesDialog;
+class KnownVariable;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateEditMatrixVectorDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateEditMatrixVectorDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateEditMatrixVectorDialog();
+
+ KnownVariable *newMatrix(QString category = QString::null);
+ KnownVariable *newVector(QString category = QString::null);
+ KnownVariable *editVariable(QString category = QString::null, KnownVariable *v = NULL, MathStructure *initial_value = NULL, bool force_value = false, bool create_vector = false);
+
+ QalculateEditNamesDialog *names_edit_dialog;
+ KnownVariable *edited_variable;
+ KComboBox *categoryCombo;
+ KLineEdit *nameEdit, *titleEdit;
+ QLabel *namesLabel, *elementsLabel;
+ QRadioButton *matrixButton, *vectorButton;
+ QTable *elementsTable;
+ QSpinBox *rowsBox, *columnsBox;
+ QPushButton *namesButton;
+
+private:
+
+ MathStructure *init_value;
+ bool force_init_value;
+
+public slots:
+
+ void typeChanged(int);
+ void rowsChanged(int);
+ void columnsChanged(int);
+ void editNames();
+ void nameChanged(const QString&);
+
+protected slots:
+
+ void slotHelp();
+ void slotOk();
+
+};
+
+#endif
diff --git a/src/qalculateeditnamesdialog.cpp b/src/qalculateeditnamesdialog.cpp
new file mode 100644
index 0000000..1a79c51
--- /dev/null
+++ b/src/qalculateeditnamesdialog.cpp
@@ -0,0 +1,275 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateeditnamesdialog.h"
+#include "qalculate_kde_utils.h"
+
+#include <klocale.h>
+#include <klistview.h>
+#include <kpushbutton.h>
+#include <qlayout.h>
+#include <klineedit.h>
+#include <qlabel.h>
+#include <qapplication.h>
+#include <kstdguiitem.h>
+
+QalculateEditNamesDialog::QalculateEditNamesDialog(int item_type, QWidget *parent, const char *name) : KDialog(parent, name, true) {
+
+ setCaption(i18n("Edit Names"));
+
+ i_type = item_type;
+
+ QVBoxLayout *layout = new QVBoxLayout(this, marginHint(), spacingHint());
+
+ namesView = new KListView(this);
+ namesView->addColumn(i18n("Name"));
+ namesView->addColumn(i18n("Abbreviation"));
+ namesView->setColumnAlignment(1, Qt::AlignCenter);
+ namesView->addColumn(i18n("Plural"));
+ namesView->setColumnAlignment(2, Qt::AlignCenter);
+ namesView->addColumn(i18n("Reference"));
+ namesView->setColumnAlignment(3, Qt::AlignCenter);
+ namesView->addColumn(i18n("Avoid Input"));
+ namesView->setColumnAlignment(4, Qt::AlignCenter);
+ namesView->addColumn(i18n("Unicode"));
+ namesView->setColumnAlignment(5, Qt::AlignCenter);
+ namesView->addColumn(i18n("Suffix"));
+ namesView->setColumnAlignment(6, Qt::AlignCenter);
+ namesView->addColumn(i18n("Case Sensitive"));
+ namesView->setColumnAlignment(7, Qt::AlignCenter);
+ namesView->setSorting(-1);
+ namesView->setItemsRenameable(true);
+ namesView->setItemsMovable(true);
+ namesView->setDragEnabled(true);
+ namesView->setAcceptDrops(true);
+ layout->addWidget(namesView);
+
+ QHBoxLayout *buttonLayout = new QHBoxLayout(layout, spacingHint());
+ newButton = new QPushButton(i18n("New"), this);
+ buttonLayout->addWidget(newButton);
+ deleteButton = new QPushButton(i18n("Delete"), this);
+ deleteButton->setEnabled(false);
+ buttonLayout->addWidget(deleteButton);
+ buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ buttonClose = new KPushButton(KStdGuiItem::close(), this);
+ buttonClose->setAutoDefault(true);
+ buttonClose->setDefault(true);
+ buttonLayout->addWidget(buttonClose);
+
+ connect(namesView, SIGNAL(selectionChanged()), this, SLOT(nameSelectionChanged()));
+ connect(buttonClose, SIGNAL(clicked()), this, SLOT(accept()));
+ connect(newButton, SIGNAL(clicked()), this, SLOT(newName()));
+ connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteName()));
+ connect(namesView, SIGNAL(clicked(QListViewItem*, const QPoint&, int)), this, SLOT(itemClicked(QListViewItem*, const QPoint&, int)));
+ connect(namesView->renameLineEdit(), SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
+
+}
+
+QalculateEditNamesDialog::~QalculateEditNamesDialog() {}
+
+void QalculateEditNamesDialog::newName() {
+ ExpressionName name;
+ QListViewItem *i = new KListViewItem(namesView, namesView->lastChild(), "", i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"));
+ namesView->setSelected(i, true);
+ qApp->processEvents();
+ namesView->rename(i, 0);
+}
+
+void QalculateEditNamesDialog::setNames(ExpressionItem *item, const QString &namestr, bool names_edited) {
+
+ if(!names_edited) {
+ deleteButton->setEnabled(false);
+ namesView->clear();
+ }
+ if(!names_edited && item && item->countNames() > 0) {
+ QListViewItem *i_prev = NULL;
+ for(size_t index = 1; index <= item->countNames(); index++) {
+ const ExpressionName *ename = &item->getName(index);
+ QListViewItem *i = new KListViewItem(namesView, i_prev);
+ i_prev = i;
+ if(ename->abbreviation)
+ i->setText(1, i18n("Yes"));
+ else
+ i->setText(1, i18n("No"));
+ if(ename->plural)
+ i->setText(2, i18n("Yes"));
+ else
+ i->setText(2, i18n("No"));
+ if(ename->reference)
+ i->setText(3, i18n("Yes"));
+ else
+ i->setText(3, i18n("No"));
+ if(ename->avoid_input)
+ i->setText(4, i18n("Yes"));
+ else
+ i->setText(4, i18n("No"));
+ if(ename->unicode)
+ i->setText(5, i18n("Yes"));
+ else
+ i->setText(5, i18n("No"));
+ if(ename->suffix)
+ i->setText(6, i18n("Yes"));
+ else
+ i->setText(6, i18n("No"));
+ if(ename->case_sensitive)
+ i->setText(7, i18n("Yes"));
+ else
+ i->setText(7, i18n("No"));
+ if(index == 1 && !namestr.isEmpty()) {
+ i->setText(0, namestr);
+ } else {
+ i->setText(0, ename->name.c_str());
+ }
+ }
+ } else if(!namestr.isEmpty()) {
+ if(names_edited) {
+ QListViewItemIterator it(namesView);
+ if(it.current())
+ it.current()->setText(0, namestr);
+ } else {
+ ExpressionName ename(namestr.ascii());
+ QListViewItem *i = new KListViewItem(namesView, ename.name.c_str());
+ if(ename.abbreviation)
+ i->setText(1, i18n("Yes"));
+ else
+ i->setText(1, i18n("No"));
+ if(ename.plural)
+ i->setText(2, i18n("Yes"));
+ else
+ i->setText(2, i18n("No"));
+ if(ename.reference)
+ i->setText(3, i18n("Yes"));
+ else
+ i->setText(3, i18n("No"));
+ if(ename.avoid_input)
+ i->setText(4, i18n("Yes"));
+ else
+ i->setText(4, i18n("No"));
+ if(ename.unicode)
+ i->setText(5, i18n("Yes"));
+ else
+ i->setText(5, i18n("No"));
+ if(ename.suffix)
+ i->setText(6, i18n("Yes"));
+ else
+ i->setText(6, i18n("No"));
+ if(ename.case_sensitive)
+ i->setText(7, i18n("Yes"));
+ else
+ i->setText(7, i18n("No"));
+ }
+ }
+}
+void QalculateEditNamesDialog::saveNames(ExpressionItem *item, const QString &str) {
+ item->clearNames();
+ QListViewItemIterator it(namesView);
+ if(it.current()) {
+ bool b = false;
+ while(it.current()) {
+ ExpressionName ename;
+ if(b || str.isEmpty())
+ ename.name = it.current()->text(0).ascii();
+ else
+ ename.name = str.ascii();
+ ename.abbreviation = (it.current()->text(1) == i18n("Yes"));
+ ename.plural = (it.current()->text(2) == i18n("Yes"));
+ ename.reference = (it.current()->text(3) == i18n("Yes"));
+ ename.avoid_input = (it.current()->text(4) == i18n("Yes"));
+ ename.unicode = (it.current()->text(5) == i18n("Yes"));
+ ename.suffix = (it.current()->text(6) == i18n("Yes"));
+ ename.case_sensitive = (it.current()->text(7) == i18n("Yes"));
+ item->addName(ename);
+ ++it;
+ b = true;
+ }
+ } else {
+ item->addName(str.ascii());
+ }
+}
+void QalculateEditNamesDialog::setNamesLE(QLineEdit *entry, QLabel *label) {
+ int index = 0;
+ QString str;
+ QListViewItemIterator it(namesView);
+ while(it.current()) {
+ if(index == 0) {
+ entry->setText(it.current()->text(0));
+ } else {
+ if(index == 1) {
+ str = "+ ";
+ } else {
+ str += ", ";
+ }
+ str += it.current()->text(0);
+ }
+ ++it;
+ index++;
+ }
+ label->setText(str);
+}
+bool QalculateEditNamesDialog::isEmpty() {
+ return namesView->childCount() <= 0;
+}
+
+void QalculateEditNamesDialog::deleteName() {
+ namesView->removeItem(namesView->selectedItem());
+}
+
+void QalculateEditNamesDialog::itemClicked(QListViewItem *i, const QPoint &, int c) {
+ if(i && c > 0) {
+ if(i->text(c) == i18n("Yes"))
+ i->setText(c, i18n("No"));
+ else
+ i->setText(c, i18n("Yes"));
+ if(c == 1)
+ i->setText(7, i->text(c));
+ }
+}
+
+void QalculateEditNamesDialog::nameSelectionChanged() {
+ deleteButton->setEnabled(namesView->selectedItem() != NULL);
+}
+
+void QalculateEditNamesDialog::nameChanged(const QString &name) {
+ if(name.isNull()) return;
+ namesView->renameLineEdit()->blockSignals(true);
+ switch(i_type) {
+ case TYPE_VARIABLE: {
+ if(!CALCULATOR->variableNameIsValid(name.ascii())) {
+ namesView->renameLineEdit()->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str());
+ }
+ break;
+ }
+ case TYPE_UNIT: {
+ if(!CALCULATOR->unitNameIsValid(name.ascii())) {
+ namesView->renameLineEdit()->setText(CALCULATOR->convertToValidUnitName(name.ascii()).c_str());
+ }
+ break;
+ }
+ case TYPE_FUNCTION: {
+ if(!CALCULATOR->functionNameIsValid(name.ascii())) {
+ namesView->renameLineEdit()->setText(CALCULATOR->convertToValidFunctionName(name.ascii()).c_str());
+ }
+ break;
+ }
+ }
+ namesView->renameLineEdit()->blockSignals(false);
+}
+
+
+#include "qalculateeditnamesdialog.moc"
diff --git a/src/qalculateeditnamesdialog.h b/src/qalculateeditnamesdialog.h
new file mode 100644
index 0000000..42f49af
--- /dev/null
+++ b/src/qalculateeditnamesdialog.h
@@ -0,0 +1,65 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEEDITNAMESDIALOG_H
+#define QALCULATEEDITNAMESDIALOG_H
+
+#include <kdialog.h>
+
+class ExpressionItem;
+class KListView;
+class QPushButton;
+class QLineEdit;
+class QLabel;
+class QListViewItem;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateEditNamesDialog : public KDialog {
+
+ Q_OBJECT
+
+public:
+
+ QalculateEditNamesDialog(int item_type, QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateEditNamesDialog();
+
+ void saveNames(ExpressionItem *item, const QString &str = QString::null);
+ void setNames(ExpressionItem *item = NULL, const QString &namestr = QString::null, bool names_edited = false);
+ bool isEmpty();
+ void setNamesLE(QLineEdit *entry, QLabel *label);
+
+ KListView* namesView;
+ QPushButton* newButton;
+ QPushButton* deleteButton;
+ QPushButton* buttonClose;
+ int i_type;
+
+public slots:
+
+ virtual void itemClicked(QListViewItem*, const QPoint&, int);
+ virtual void newName();
+ virtual void deleteName();
+ virtual void nameChanged(const QString&);
+ virtual void nameSelectionChanged();
+
+};
+
+#endif
diff --git a/src/qalculateeditunitdialog.cpp b/src/qalculateeditunitdialog.cpp
new file mode 100644
index 0000000..3bf155f
--- /dev/null
+++ b/src/qalculateeditunitdialog.cpp
@@ -0,0 +1,425 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateeditunitdialog.h"
+#include "qalculate_kde_utils.h"
+#include "qalculateeditnamesdialog.h"
+
+#include <qgrid.h>
+#include <klineedit.h>
+#include <qpushbutton.h>
+#include <kcombobox.h>
+#include <qlabel.h>
+#include <klocale.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qcheckbox.h>
+#include <kmessagebox.h>
+#include <qgroupbox.h>
+#include <qspinbox.h>
+#include <qlayout.h>
+#include <kapplication.h>
+
+extern PrintOptions printops;
+extern EvaluationOptions evalops;
+extern tree_struct unit_cats;
+
+QalculateEditUnitDialog::QalculateEditUnitDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Unit"), Ok | Cancel | Help, Ok, true) {
+
+ names_edit_dialog = NULL;
+ edited_unit = NULL;
+
+ QVBox *box = makeVBoxMainWidget();
+
+ grid1 = new QGroupBox(1, Qt::Horizontal, i18n("Name"), box);
+ grid1->setInsideMargin(spacingHint());
+ grid1->setInsideSpacing(spacingHint());
+ QWidget *widget = new QWidget(grid1);
+ QGridLayout *grid = new QGridLayout(widget, 1, 1, 0, spacingHint());
+ grid->addWidget(new QLabel(i18n("Name:"), widget), 0, 0);
+ nameEdit = new KLineEdit(widget);
+ grid->addWidget(nameEdit, 0, 1);
+ QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
+ namesLabel = new QLabel(widget);
+ namesLabel->setAlignment(Qt::AlignRight);
+ namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ hbox->addWidget(namesLabel);
+ namesButton = new QPushButton(i18n("Names Details"), widget);
+ hbox->addWidget(namesButton);
+ grid->addWidget(new QLabel(i18n("Descriptive name:"), widget), 2, 0);
+ titleEdit = new KLineEdit(widget);
+ grid->addWidget(titleEdit, 2, 1);
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 3, 3, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ hideButton = new QCheckBox(i18n("Hide unit"), widget);
+ hbox->addWidget(hideButton);
+
+ grid2 = new QGroupBox(1, Qt::Horizontal, i18n("Type"), box);
+ grid2->setInsideMargin(spacingHint());
+ grid2->setInsideSpacing(spacingHint());
+ widget = new QWidget(grid2);
+ grid = new QGridLayout(widget, 1, 1, 0, spacingHint());
+ grid->addWidget(new QLabel(i18n("Class:"), widget), 0, 0);
+ classCombo = new KComboBox(widget);
+ grid->addWidget(classCombo, 0, 1);
+ classCombo->insertItem(i18n("Base Unit"));
+ classCombo->insertItem(i18n("Alias"));
+ classCombo->insertItem(i18n("Composite Unit"));
+ classCombo->setMaximumWidth(250);
+ grid->addWidget(new QLabel(i18n("Category:"), widget), 1, 0);
+ categoryCombo = new KComboBox(widget);
+ grid->addWidget(categoryCombo, 1, 1);
+ categoryCombo->setMaximumWidth(250);
+ categoryCombo->setEditable(true);
+ grid->addWidget(new QLabel(i18n("System:"), widget), 2, 0);
+ systemCombo = new KComboBox(widget);
+ grid->addWidget(systemCombo, 2, 1);
+ systemCombo->insertItem(i18n("SI"));
+ systemCombo->insertItem(i18n("CGS"));
+ systemCombo->insertItem(i18n("Imperial"));
+ systemCombo->insertItem(i18n("US Survey"));
+ systemCombo->setMaximumWidth(250);
+ systemCombo->setEditable(true);
+
+ grid3 = new QGroupBox(1, Qt::Horizontal, i18n("Relation"), box);
+ grid3->setInsideMargin(spacingHint());
+ grid3->setInsideSpacing(spacingHint());
+ widget = new QWidget(grid3);
+ grid = new QGridLayout(widget, 1, 1, 0, spacingHint());
+ grid->addWidget(new QLabel(i18n("Base unit:"), widget), 0, 0);
+ baseEdit = new KLineEdit(widget);
+ grid->addWidget(baseEdit, 0, 1);
+ exponentLabel = new QLabel(i18n("Exponent:"), widget);
+ grid->addWidget(exponentLabel, 1, 0);
+ exponentBox = new QSpinBox(-9, 9, 1, widget);
+ grid->addWidget(exponentBox, 1, 1);
+ relationLabel = new QLabel(i18n("Relation:"), widget);
+ grid->addWidget(relationLabel, 2, 0);
+ relationEdit = new KLineEdit(widget);
+ grid->addWidget(relationEdit, 2, 1);
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 3, 3, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ relationExactButton = new QCheckBox(i18n("Relation is exact"), widget);
+ hbox->addWidget(relationExactButton);
+ inverseRelationLabel = new QLabel(i18n("Inverse relation:"), widget);
+ grid->addWidget(inverseRelationLabel, 4, 0);
+ inverseRelationEdit = new KLineEdit(widget);
+ grid->addWidget(inverseRelationEdit, 4, 1);
+
+ connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
+ connect(classCombo, SIGNAL(activated(int)), this, SLOT(classChanged(int)));
+ connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
+
+}
+
+QalculateEditUnitDialog::~QalculateEditUnitDialog() {}
+
+void QalculateEditUnitDialog::slotHelp() {
+ KApplication::kApplication()->invokeHelp("qalculate-unit-creation");
+}
+void QalculateEditUnitDialog::slotOk() {
+
+ string str = nameEdit->text().ascii();
+ remove_blank_ends(str);
+ if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
+ //no name -- open dialog again
+ nameEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty name field"));
+ return;
+ }
+ //unit with the same name exists -- overwrite or open dialog again
+ if((!edited_unit || !edited_unit->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->unitNameTaken(str, edited_unit) && KMessageBox::questionYesNo(this, i18n("A variable or unit with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
+ nameEdit->setFocus();
+ return;
+ }
+
+ Unit *u = edited_unit;
+
+ bool add_unit = false;
+ if(u) {
+ //edited an existing unit -- update unit
+ u->setLocal(true);
+ int i1 = classCombo->currentItem();
+ switch(u->subtype()) {
+ case SUBTYPE_ALIAS_UNIT: {
+ if(i1 != 1) {
+ u->destroy();
+ u = NULL;
+ break;
+ }
+ if(!u->isBuiltin()) {
+ AliasUnit *au = (AliasUnit*) u;
+ Unit *bu = CALCULATOR->getUnit(baseEdit->text().ascii());
+ if(!bu) bu = CALCULATOR->getCompositeUnit(baseEdit->text().ascii());
+ if(!bu) {
+ baseEdit->setFocus();
+ KMessageBox::error(this, i18n("Base unit does not exist"));
+ return;
+ }
+ au->setBaseUnit(bu);
+ au->setExpression(CALCULATOR->unlocalizeExpression(relationEdit->text().ascii(), evalops.parse_options));
+ au->setInverseExpression(CALCULATOR->unlocalizeExpression(inverseRelationEdit->text().ascii(), evalops.parse_options));
+ au->setExponent(exponentBox->value());
+ au->setApproximate(!relationExactButton->isChecked());
+ }
+ break;
+ }
+ case SUBTYPE_COMPOSITE_UNIT: {
+ if(i1 != 2) {
+ u->destroy();
+ u = NULL;
+ break;
+ }
+ if(!u->isBuiltin()) {
+ ((CompositeUnit*) u)->setBaseExpression(baseEdit->text().ascii());
+ }
+ break;
+ }
+ case SUBTYPE_BASE_UNIT: {
+ if(i1 != 0) {
+ u->destroy();
+ u = NULL;
+ break;
+ }
+ break;
+ }
+ }
+ if(u) {
+ u->setTitle(titleEdit->text().ascii());
+ u->setCategory(categoryCombo->lineEdit()->text().ascii());
+ }
+ }
+ if(!u) {
+ //new unit
+ switch(classCombo->currentItem()) {
+ case 1: {
+ Unit *bu = CALCULATOR->getUnit(baseEdit->text().ascii());
+ if(!bu) bu = CALCULATOR->getCompositeUnit(baseEdit->text().ascii());
+ if(!bu) {
+ baseEdit->setFocus();
+ KMessageBox::error(this, i18n("Base unit does not exist"));
+ return;
+ }
+ u = new AliasUnit(categoryCombo->lineEdit()->text().ascii(), "", "", "", titleEdit->text().ascii(), bu, CALCULATOR->unlocalizeExpression(relationEdit->text().ascii(), evalops.parse_options), exponentBox->value(), CALCULATOR->unlocalizeExpression(inverseRelationEdit->text().ascii(), evalops.parse_options), true);
+ ((AliasUnit*) u)->setApproximate(!relationExactButton->isChecked());
+ break;
+ }
+ case 2: {
+ CompositeUnit *cu = new CompositeUnit(categoryCombo->lineEdit()->text().ascii(), "", titleEdit->text().ascii(), baseEdit->text().ascii(), true);
+ u = cu;
+ break;
+ }
+ default: {
+ u = new Unit(categoryCombo->lineEdit()->text().ascii(), "", "", "", titleEdit->text().ascii(), true);
+ break;
+ }
+ }
+ add_unit = true;
+ }
+ if(u) {
+ u->setHidden(hideButton->isChecked());
+ if(!u->isBuiltin()) {
+ u->setSystem(systemCombo->lineEdit()->text().ascii());
+ if(names_edit_dialog) {
+ names_edit_dialog->saveNames(u, str.c_str());
+ } else {
+ if(u->countNames() == 0) {
+ ExpressionName ename(str);
+ ename.reference = true;
+ u->setName(ename, 1);
+ } else {
+ u->setName(str, 1);
+ }
+ }
+ }
+ if(add_unit) {
+ CALCULATOR->addUnit(u);
+ }
+ }
+ edited_unit = u;
+
+ accept();
+
+}
+
+
+void QalculateEditUnitDialog::classChanged(int i) {
+ exponentBox->setEnabled(i == 1);
+ relationEdit->setEnabled(i == 1);
+ relationExactButton->setEnabled(i == 1);
+ inverseRelationEdit->setEnabled(i == 1);
+ exponentLabel->setEnabled(i == 1);
+ relationLabel->setEnabled(i == 1);
+ inverseRelationLabel->setEnabled(i == 1);
+ grid3->setEnabled(i != 0);
+}
+
+Unit *QalculateEditUnitDialog::editUnit(QString category, Unit *u) {
+
+ nameEdit->setFocus();
+
+ if(names_edit_dialog) {
+ delete names_edit_dialog;
+ names_edit_dialog = NULL;
+ }
+ edited_unit = u;
+ if(u) {
+ if(u->isLocal())
+ setCaption(i18n("Edit Unit"));
+ else
+ setCaption(i18n("Edit Unit (global)"));
+ } else {
+ setCaption(i18n("New Unit"));
+ }
+
+ //QStringList cats;
+ QString catstr;
+ categoryCombo->clear();
+ tree_struct *item, *item2;
+ unit_cats.it = unit_cats.items.begin();
+ if(unit_cats.it != unit_cats.items.end()) {
+ item = &*unit_cats.it;
+ ++unit_cats.it;
+ item->it = item->items.begin();
+ } else {
+ item = NULL;
+ }
+
+ catstr = "";
+ while(item) {
+ if(!catstr.isEmpty()) catstr += "/";
+ catstr += item->item.c_str();
+ categoryCombo->insertItem(catstr);
+ while(item && item->it == item->items.end()) {
+ int str_i = catstr.findRev("/");
+ if(str_i < 0) {
+ catstr = "";
+ } else {
+ catstr.truncate(str_i);
+ }
+ item = item->parent;
+ }
+ if(item) {
+ item2 = &*item->it;
+ ++item->it;
+ item = item2;
+ item->it = item->items.begin();
+ }
+ }
+
+ categoryCombo->lineEdit()->setText(category);
+ //clear entries
+ nameEdit->clear();
+ titleEdit->clear();
+ baseEdit->clear();
+ relationEdit->clear();
+ inverseRelationEdit->clear();
+ systemCombo->lineEdit()->clear();
+ exponentBox->setValue(1);
+ namesLabel->clear();
+ actionButton(Ok)->setEnabled(true);
+ nameEdit->setReadOnly(u && u->isBuiltin());
+ relationEdit->setReadOnly(u && u->isBuiltin());
+ inverseRelationEdit->setReadOnly(u && u->isBuiltin());
+ systemCombo->setEnabled(!u || !u->isBuiltin());
+ classCombo->setEnabled(!u || !u->isBuiltin());
+ baseEdit->setReadOnly(u && u->isBuiltin());
+ if(u) {
+ //fill in original parameters
+ if(u->subtype() == SUBTYPE_BASE_UNIT) {
+ classCombo->setCurrentItem(0);
+ classChanged(0);
+ } else if(u->subtype() == SUBTYPE_ALIAS_UNIT) {
+ classCombo->setCurrentItem(1);
+ classChanged(1);
+ } else if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) {
+ classCombo->setCurrentItem(2);
+ classChanged(2);
+ }
+
+ set_name_label_and_entry(u, nameEdit, namesLabel);
+ systemCombo->lineEdit()->setText(u->system().c_str());
+ hideButton->setChecked(u->isHidden());
+ categoryCombo->lineEdit()->setText(u->category().c_str());
+ titleEdit->setText(u->title(false).c_str());
+
+ switch(u->subtype()) {
+ case SUBTYPE_ALIAS_UNIT: {
+ AliasUnit *au = (AliasUnit*) u;
+ baseEdit->setText(((CompositeUnit*) (au->firstBaseUnit()))->preferredDisplayName(printops.abbreviate_names, true, false, false, &can_display_unicode_string_function, (void*) baseEdit).name.c_str());
+ exponentBox->setValue(au->firstBaseExponent());
+ relationEdit->setText(CALCULATOR->localizeExpression(au->expression()).c_str());
+ inverseRelationEdit->setText(CALCULATOR->localizeExpression(au->inverseExpression()).c_str());
+ relationExactButton->setChecked(!au->isApproximate());
+ relationEdit->setEnabled(true);
+ inverseRelationEdit->setEnabled(true);
+ relationExactButton->setEnabled(!u->isBuiltin());
+ exponentBox->setEnabled(!u->isBuiltin());
+ baseEdit->setEnabled(true);
+ break;
+ }
+ case SUBTYPE_COMPOSITE_UNIT: {
+ baseEdit->setText(((CompositeUnit*) u)->print(false, printops.abbreviate_names, true, &can_display_unicode_string_function, (void*) baseEdit).c_str());
+ baseEdit->setEnabled(true);
+ }
+ }
+ } else {
+ //default values
+ hideButton->setChecked(false);
+ relationExactButton->setChecked(true);
+ relationEdit->setText("1");
+ classCombo->setCurrentItem(1);
+ classChanged(1);
+ }
+
+ if(exec() == QDialog::Accepted) {
+ u = edited_unit;
+ edited_unit = NULL;
+ return u;
+ }
+ edited_unit = NULL;
+ return NULL;
+}
+
+void QalculateEditUnitDialog::editNames() {
+ if(!names_edit_dialog) {
+ names_edit_dialog = new QalculateEditNamesDialog(TYPE_UNIT, this);
+ names_edit_dialog->setNames(edited_unit, nameEdit->text(), false);
+ } else {
+ names_edit_dialog->setNames(edited_unit, nameEdit->text(), true);
+ }
+ names_edit_dialog->exec();
+ names_edit_dialog->setNamesLE(nameEdit, namesLabel);
+}
+
+void QalculateEditUnitDialog::nameChanged(const QString &name) {
+ if(name.isNull()) return;
+ if(!CALCULATOR->unitNameIsValid(name.ascii())) {
+ nameEdit->blockSignals(true);
+ nameEdit->setText(CALCULATOR->convertToValidUnitName(name.ascii()).c_str());
+ nameEdit->blockSignals(false);
+ }
+}
+
+
+#include "qalculateeditunitdialog.moc"
+
diff --git a/src/qalculateeditunitdialog.h b/src/qalculateeditunitdialog.h
new file mode 100644
index 0000000..02655d8
--- /dev/null
+++ b/src/qalculateeditunitdialog.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEEDITUNITDIALOG_H
+#define QALCULATEEDITUNITDIALOG_H
+
+#include <kdialogbase.h>
+
+class QLabel;
+class KComboBox;
+class KLineEdit;
+class QCheckBox;
+class QPushButton;
+class QSpinBox;
+class MathStructure;
+class QalculateEditNamesDialog;
+class Unit;
+class QGroupBox;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateEditUnitDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateEditUnitDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateEditUnitDialog();
+
+ Unit *editUnit(QString category = QString::null, Unit *u = NULL);
+
+ QalculateEditNamesDialog *names_edit_dialog;
+ Unit *edited_unit;
+ KComboBox *categoryCombo, *classCombo, *systemCombo;
+ KLineEdit *nameEdit, *titleEdit, *baseEdit, *relationEdit, *inverseRelationEdit;
+ QLabel *namesLabel, *exponentLabel, *relationLabel, *inverseRelationLabel;
+ QCheckBox *relationExactButton, *hideButton;
+ QPushButton *namesButton;
+ QSpinBox *exponentBox;
+ QGroupBox *grid1, *grid2, *grid3;
+
+public slots:
+
+ void editNames();
+ void classChanged(int);
+ void nameChanged(const QString&);
+
+protected slots:
+
+ void slotHelp();
+ void slotOk();
+
+};
+
+#endif
diff --git a/src/qalculateeditunknownvariabledialog.cpp b/src/qalculateeditunknownvariabledialog.cpp
new file mode 100644
index 0000000..4e7dc42
--- /dev/null
+++ b/src/qalculateeditunknownvariabledialog.cpp
@@ -0,0 +1,308 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateeditunknownvariabledialog.h"
+#include "qalculate_kde_utils.h"
+#include "qalculateeditnamesdialog.h"
+
+#include <qgrid.h>
+#include <klineedit.h>
+#include <qpushbutton.h>
+#include <kcombobox.h>
+#include <qlabel.h>
+#include <klocale.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qcheckbox.h>
+#include <kmessagebox.h>
+#include <qlayout.h>
+#include <kapplication.h>
+
+extern PrintOptions printops;
+extern tree_struct variable_cats;
+
+QalculateEditUnknownVariableDialog::QalculateEditUnknownVariableDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Variable"), Ok | Cancel | Help, Ok, true) {
+
+ names_edit_dialog = NULL;
+ edited_unknown = NULL;
+
+ setMainWidget(new QWidget(this));
+ QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
+ grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 0, 0);
+ nameEdit = new KLineEdit(mainWidget());
+ grid->addWidget(nameEdit, 0, 1);
+ QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
+ namesLabel = new QLabel(mainWidget());
+ namesLabel->setAlignment(Qt::AlignRight);
+ namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ hbox->addWidget(namesLabel);
+ namesButton = new QPushButton(i18n("Names Details"), mainWidget());
+ hbox->addWidget(namesButton);
+ assumptionsBox = new QCheckBox(i18n("Custom assumptions:"), mainWidget());
+ grid->addMultiCellWidget(assumptionsBox, 2, 2, 0, 1);
+ typeLabel = new QLabel(i18n("Type"), mainWidget());
+ grid->addWidget(typeLabel, 3, 0);
+ typeCombo = new KComboBox(mainWidget());
+ typeCombo->setMaximumWidth(250);
+ typeCombo->setEditable(false);
+ typeCombo->insertItem(i18n("Unknown"));
+ typeCombo->insertItem(i18n("Not Matrix"));
+ typeCombo->insertItem(i18n("Number"));
+ typeCombo->insertItem(i18n("Complex Number"));
+ typeCombo->insertItem(i18n("Real Number"));
+ typeCombo->insertItem(i18n("Rational Number"));
+ typeCombo->insertItem(i18n("Integer"));
+ grid->addWidget(typeCombo, 3, 1);
+ signLabel = new QLabel(i18n("Sign"), mainWidget());
+ grid->addWidget(signLabel, 4, 0);
+ signCombo = new KComboBox(mainWidget());
+ signCombo->setMaximumWidth(250);
+ signCombo->setEditable(false);
+ signCombo->insertItem(i18n("Unknown"));
+ signCombo->insertItem(i18n("Positive"));
+ signCombo->insertItem(i18n("Non-Negative"));
+ signCombo->insertItem(i18n("Negative"));
+ signCombo->insertItem(i18n("Non-Positive"));
+ signCombo->insertItem(i18n("Non-Zero"));
+ grid->addWidget(signCombo, 4, 1);
+ grid->addWidget(new QLabel(i18n("Category:"), mainWidget()), 5, 0);
+ categoryCombo = new KComboBox(mainWidget());
+ categoryCombo->setMaximumWidth(250);
+ categoryCombo->setEditable(true);
+ grid->addWidget(categoryCombo, 5, 1);
+ grid->addWidget(new QLabel(i18n("Descriptive name:"), mainWidget()), 6, 0);
+ titleEdit = new KLineEdit(mainWidget());
+ grid->addWidget(titleEdit, 6, 1);
+
+ connect(assumptionsBox, SIGNAL(toggled(bool)), typeCombo, SLOT(setEnabled(bool)));
+ connect(assumptionsBox, SIGNAL(toggled(bool)), signCombo, SLOT(setEnabled(bool)));
+ connect(assumptionsBox, SIGNAL(toggled(bool)), typeLabel, SLOT(setEnabled(bool)));
+ connect(assumptionsBox, SIGNAL(toggled(bool)), signLabel, SLOT(setEnabled(bool)));
+ connect(typeCombo, SIGNAL(activated(int)), this, SLOT(typeComboActivated(int)));
+ connect(signCombo, SIGNAL(activated(int)), this, SLOT(signComboActivated(int)));
+ connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
+ connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
+
+}
+
+QalculateEditUnknownVariableDialog::~QalculateEditUnknownVariableDialog() {}
+
+void QalculateEditUnknownVariableDialog::typeComboActivated(int i) {
+ if((AssumptionType) i <= ASSUMPTION_TYPE_COMPLEX && (AssumptionSign) signCombo->currentItem() != ASSUMPTION_SIGN_NONZERO) {
+ signCombo->blockSignals(true);
+ signCombo->setCurrentItem(ASSUMPTION_SIGN_UNKNOWN);
+ signCombo->blockSignals(false);
+ }
+}
+void QalculateEditUnknownVariableDialog::signComboActivated(int i) {
+ if((AssumptionSign) i != ASSUMPTION_SIGN_NONZERO && (AssumptionSign) i != ASSUMPTION_SIGN_UNKNOWN && (AssumptionType) typeCombo->currentItem() <= ASSUMPTION_TYPE_COMPLEX) {
+ typeCombo->blockSignals(true);
+ typeCombo->setCurrentItem(ASSUMPTION_TYPE_REAL);
+ typeCombo->blockSignals(false);
+ }
+}
+
+void QalculateEditUnknownVariableDialog::slotHelp() {
+ KApplication::kApplication()->invokeHelp("qalculate-variable-creation");
+}
+void QalculateEditUnknownVariableDialog::slotOk() {
+
+ string str = nameEdit->text().ascii();
+ remove_blank_ends(str);
+ if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
+ //no name -- open dialog again
+ nameEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty name field"));
+ return;
+ }
+ //variable with the same name exists -- overwrite or open dialog again
+ if((!edited_unknown || !edited_unknown->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->variableNameTaken(str, edited_unknown) && KMessageBox::questionYesNo(this, i18n("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
+ nameEdit->setFocus();
+ return;
+ }
+
+ UnknownVariable *v = edited_unknown;
+ if(!v) {
+ //no need to create a new variable when a variable with the same name exists
+ Variable *var = CALCULATOR->getActiveVariable(str);
+ if(var && var->isLocal() && !var->isKnown()) v = (UnknownVariable*) var;
+ }
+ bool add_var = false;
+ if(v) {
+ //update existing variable
+ v->setLocal(true);
+ } else {
+ //new unknown variable
+ v = new UnknownVariable("", "", "", true);
+ add_var = true;
+ }
+ if(!v->isBuiltin()) {
+ if(assumptionsBox->isChecked()) {
+ if(!v->assumptions()) v->setAssumptions(new Assumptions());
+ v->assumptions()->setType((AssumptionType) typeCombo->currentItem());
+ v->assumptions()->setSign((AssumptionSign) signCombo->currentItem());
+ } else {
+ v->setAssumptions(NULL);
+ }
+ }
+ v->setCategory(categoryCombo->lineEdit()->text().ascii());
+ v->setTitle(titleEdit->text().ascii());
+ if(!v->isBuiltin()) {
+ if(names_edit_dialog) {
+ names_edit_dialog->saveNames(v, str.c_str());
+ } else {
+ if(v->countNames() == 0) {
+ ExpressionName ename(str);
+ ename.reference = true;
+ v->setName(ename, 1);
+ } else {
+ v->setName(str, 1);
+ }
+ }
+ }
+ if(add_var) {
+ CALCULATOR->addVariable(v);
+ }
+ edited_unknown = v;
+ accept();
+}
+
+
+UnknownVariable *QalculateEditUnknownVariableDialog::editVariable(QString category, UnknownVariable *v) {
+
+ nameEdit->setFocus();
+
+ if(names_edit_dialog) {
+ delete names_edit_dialog;
+ names_edit_dialog = NULL;
+ }
+ edited_unknown = v;
+ if(v) {
+ if(v->isLocal())
+ setCaption(i18n("Edit Unknown Variable"));
+ else
+ setCaption(i18n("Edit Unknown Variable (global)"));
+ } else {
+ setCaption(i18n("New Unknown Variable"));
+ }
+
+ actionButton(Ok)->setEnabled(true);
+
+ namesLabel->setText("");
+
+ //QStringList cats;
+ QString catstr;
+ categoryCombo->clear();
+ tree_struct *item, *item2;
+ variable_cats.it = variable_cats.items.begin();
+ if(variable_cats.it != variable_cats.items.end()) {
+ item = &*variable_cats.it;
+ ++variable_cats.it;
+ item->it = item->items.begin();
+ } else {
+ item = NULL;
+ }
+
+ catstr = "";
+ while(item) {
+ if(!catstr.isEmpty()) catstr += "/";
+ catstr += item->item.c_str();
+ categoryCombo->insertItem(catstr);
+ while(item && item->it == item->items.end()) {
+ int str_i = catstr.findRev("/");
+ if(str_i < 0) {
+ catstr = "";
+ } else {
+ catstr.truncate(str_i);
+ }
+ item = item->parent;
+ }
+ if(item) {
+ item2 = &*item->it;
+ ++item->it;
+ item = item2;
+ item->it = item->items.begin();
+ }
+ }
+
+ if(v) {
+ //fill in original parameters
+ set_name_label_and_entry(v, nameEdit, namesLabel);
+ nameEdit->setReadOnly(v->isBuiltin());
+ assumptionsBox->setEnabled(!v->isBuiltin());
+ categoryCombo->lineEdit()->setText(v->category().c_str());
+ titleEdit->setText(v->title(false).c_str());
+ if(v->assumptions()) {
+ assumptionsBox->setChecked(true);
+ typeCombo->setCurrentItem(v->assumptions()->type());
+ signCombo->setCurrentItem(v->assumptions()->sign());
+ } else {
+ assumptionsBox->setChecked(false);
+ typeCombo->setCurrentItem(CALCULATOR->defaultAssumptions()->type());
+ signCombo->setCurrentItem(CALCULATOR->defaultAssumptions()->sign());
+ }
+ } else {
+ nameEdit->setReadOnly(false);
+ assumptionsBox->setChecked(true);
+
+ //fill in default values
+ nameEdit->setText(CALCULATOR->getName().c_str());
+ namesLabel->setText("");
+ categoryCombo->lineEdit()->setText(category);
+ titleEdit->setText("");
+ typeCombo->setCurrentItem(CALCULATOR->defaultAssumptions()->type());
+ signCombo->setCurrentItem(CALCULATOR->defaultAssumptions()->sign());
+ }
+ signLabel->setEnabled(!v || (!v->isBuiltin() && v->assumptions()));
+ typeLabel->setEnabled(!v || (!v->isBuiltin() && v->assumptions()));
+ signCombo->setEnabled(!v || (!v->isBuiltin() && v->assumptions()));
+ typeCombo->setEnabled(!v || (!v->isBuiltin() && v->assumptions()));
+
+ if(exec() == QDialog::Accepted) {
+ v = edited_unknown;
+ edited_unknown = NULL;
+ return v;
+ }
+ edited_unknown = NULL;
+ return NULL;
+}
+
+void QalculateEditUnknownVariableDialog::editNames() {
+ if(!names_edit_dialog) {
+ names_edit_dialog = new QalculateEditNamesDialog(TYPE_VARIABLE, this);
+ names_edit_dialog->setNames(edited_unknown, nameEdit->text(), false);
+ } else {
+ names_edit_dialog->setNames(edited_unknown, nameEdit->text(), true);
+ }
+ names_edit_dialog->exec();
+ names_edit_dialog->setNamesLE(nameEdit, namesLabel);
+}
+
+void QalculateEditUnknownVariableDialog::nameChanged(const QString &name) {
+ if(name.isNull()) return;
+ if(!CALCULATOR->variableNameIsValid(name.ascii())) {
+ nameEdit->blockSignals(true);
+ nameEdit->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str());
+ nameEdit->blockSignals(false);
+ }
+}
+
+#include "qalculateeditunknownvariabledialog.moc"
+
diff --git a/src/qalculateeditunknownvariabledialog.h b/src/qalculateeditunknownvariabledialog.h
new file mode 100644
index 0000000..cfa499e
--- /dev/null
+++ b/src/qalculateeditunknownvariabledialog.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEEDITUNKNOWNVARIABLEDIALOG_H
+#define QALCULATEEDITUNKNOWNVARIABLEDIALOG_H
+
+#include <kdialogbase.h>
+
+class QLabel;
+class KComboBox;
+class KLineEdit;
+class QPushButton;
+class MathStructure;
+class QalculateEditNamesDialog;
+class UnknownVariable;
+class QCheckBox;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateEditUnknownVariableDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateEditUnknownVariableDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateEditUnknownVariableDialog();
+
+ UnknownVariable *editVariable(QString category = QString::null, UnknownVariable *v = NULL);
+
+ QalculateEditNamesDialog *names_edit_dialog;
+ UnknownVariable *edited_unknown;
+ KComboBox *categoryCombo, *signCombo, *typeCombo;
+ KLineEdit *nameEdit, *titleEdit;
+ QLabel *namesLabel, *signLabel, *typeLabel;
+ QPushButton *namesButton;
+ QCheckBox *assumptionsBox;
+
+public slots:
+
+ void editNames();
+ void nameChanged(const QString&);
+ void signComboActivated(int);
+ void typeComboActivated(int);
+
+protected slots:
+
+ void slotHelp();
+ void slotOk();
+
+};
+
+#endif
diff --git a/src/qalculateeditvariabledialog.cpp b/src/qalculateeditvariabledialog.cpp
new file mode 100644
index 0000000..013dec0
--- /dev/null
+++ b/src/qalculateeditvariabledialog.cpp
@@ -0,0 +1,304 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateeditvariabledialog.h"
+#include "qalculate_kde_utils.h"
+#include "qalculateeditnamesdialog.h"
+
+#include <qgrid.h>
+#include <klineedit.h>
+#include <qpushbutton.h>
+#include <kcombobox.h>
+#include <qlabel.h>
+#include <klocale.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qcheckbox.h>
+#include <kmessagebox.h>
+#include <qlayout.h>
+#include <kapplication.h>
+
+extern PrintOptions printops;
+extern EvaluationOptions evalops;
+extern tree_struct variable_cats;
+
+QalculateEditVariableDialog::QalculateEditVariableDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Variable"), Ok | Cancel | Help, Ok, true) {
+
+ names_edit_dialog = NULL;
+ edited_variable = NULL;
+
+ setMainWidget(new QWidget(this));
+ QGridLayout *grid = new QGridLayout(mainWidget(), 6, 2, 0, spacingHint());
+
+ nameLabel = new QLabel(i18n("Name:"), mainWidget());
+ grid->addWidget(nameLabel, 0, 0);
+ nameEdit = new KLineEdit(mainWidget());
+ grid->addWidget(nameEdit, 0, 1);
+
+ QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
+ namesLabel = new QLabel(mainWidget());
+ namesLabel->setAlignment(Qt::AlignRight);
+ namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ hbox->addWidget(namesLabel);
+ namesButton = new QPushButton(i18n("Names Details"), mainWidget());
+ hbox->addWidget(namesButton);
+
+ valueLabel = new QLabel(i18n("Value:"), mainWidget());
+ grid->addWidget(valueLabel, 2, 0);
+ valueEdit = new KLineEdit(mainWidget());
+ grid->addWidget(valueEdit, 2, 1);
+
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 3, 3, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ valueExactButton = new QCheckBox(i18n("Value is exact"), mainWidget());
+ hbox->addWidget(valueExactButton);
+
+ grid->addWidget(new QLabel(i18n("Category:"), mainWidget()), 4, 0);
+ categoryCombo = new KComboBox(mainWidget());
+ grid->addWidget(categoryCombo, 4, 1);
+ categoryCombo->setMaximumWidth(250);
+ categoryCombo->setEditable(true);
+
+ titleLabel = new QLabel(i18n("Descriptive name:"), mainWidget());
+ grid->addWidget(titleLabel, 5, 0);
+ titleEdit = new KLineEdit(mainWidget());
+ grid->addWidget(titleEdit, 5, 1);
+
+ connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
+ connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
+
+}
+
+QalculateEditVariableDialog::~QalculateEditVariableDialog() {}
+
+void QalculateEditVariableDialog::slotHelp() {
+ KApplication::kApplication()->invokeHelp("qalculate-variable-creation");
+}
+
+void QalculateEditVariableDialog::slotOk() {
+ string str = nameEdit->text().ascii();
+ remove_blank_ends(str);
+ if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
+ //no name -- open dialog again
+ nameEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty name field"));
+ return;
+ }
+ string str2 = valueEdit->text().ascii();
+ remove_blank_ends(str2);
+ if(!(init_value && force_init_value) && str2.empty()) {
+ //no value -- open dialog again
+ valueEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty value field"));
+ return;
+ }
+ //variable with the same name exists -- overwrite or open dialog again
+ if((!edited_variable || !edited_variable->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->variableNameTaken(str, edited_variable) && KMessageBox::questionYesNo(this, i18n("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
+ nameEdit->setFocus();
+ return;
+ }
+ KnownVariable *v = edited_variable;
+ if(!v) {
+ //no need to create a new variable when a variable with the same name exists
+ Variable *var = CALCULATOR->getActiveVariable(str);
+ if(var && var->isLocal() && var->isKnown()) v = (KnownVariable*) var;
+ }
+ bool add_var = false;
+ if(v) {
+ //update existing variable
+ v->setLocal(true);
+ if(!v->isBuiltin()) {
+ if(force_init_value && init_value) {
+ v->set(*init_value);
+ } else {
+ v->set(CALCULATOR->unlocalizeExpression(valueEdit->text().ascii(), evalops.parse_options));
+ v->setApproximate(!valueExactButton->isChecked());
+ }
+ }
+ } else {
+ //new variable
+ if(force_init_value && init_value) {
+ //forced value
+ v = new KnownVariable("", "", *init_value, "", true);
+ } else {
+ v = new KnownVariable("", "", CALCULATOR->unlocalizeExpression(valueEdit->text().ascii(), evalops.parse_options), "", true);
+ v->setApproximate(!valueExactButton->isChecked());
+ }
+ add_var = true;
+ }
+ v->setCategory(categoryCombo->lineEdit()->text().ascii());
+ v->setTitle(titleEdit->text().ascii());
+ if(!v->isBuiltin()) {
+ if(names_edit_dialog) {
+ names_edit_dialog->saveNames(v, str.c_str());
+ } else {
+ if(v->countNames() == 0) {
+ ExpressionName ename(str);
+ ename.reference = true;
+ v->setName(ename, 1);
+ } else {
+ v->setName(str, 1);
+ }
+ }
+ }
+ if(add_var) {
+ CALCULATOR->addVariable(v);
+ }
+ edited_variable = v;
+ accept();
+}
+
+KnownVariable *QalculateEditVariableDialog::editVariable(QString category, KnownVariable *v, MathStructure *initial_value, bool force_value) {
+
+ nameEdit->setFocus();
+
+ if(names_edit_dialog) {
+ delete names_edit_dialog;
+ names_edit_dialog = NULL;
+ }
+ edited_variable = v;
+ if(v) {
+ if(v->isLocal()) {
+ setCaption(i18n("Edit Variable"));
+ } else {
+ setCaption(i18n("Edit Variable (global)"));
+ }
+ } else {
+ setCaption(i18n("New Variable"));
+ }
+
+ actionButton(Ok)->setEnabled(true);
+
+ namesLabel->setText("");
+
+ //QStringList cats;
+ QString catstr;
+ categoryCombo->clear();
+ tree_struct *item, *item2;
+ variable_cats.it = variable_cats.items.begin();
+ if(variable_cats.it != variable_cats.items.end()) {
+ item = &*variable_cats.it;
+ ++variable_cats.it;
+ item->it = item->items.begin();
+ } else {
+ item = NULL;
+ }
+
+ catstr = "";
+ while(item) {
+ if(!catstr.isEmpty()) catstr += "/";
+ catstr += item->item.c_str();
+ categoryCombo->insertItem(catstr);
+ while(item && item->it == item->items.end()) {
+ int str_i = catstr.findRev("/");
+ if(str_i < 0) {
+ catstr = "";
+ } else {
+ catstr.truncate(str_i);
+ }
+ item = item->parent;
+ }
+ if(item) {
+ item2 = &*item->it;
+ ++item->it;
+ item = item2;
+ item->it = item->items.begin();
+ }
+ }
+
+ if(initial_value && force_value) {
+ valueEdit->hide();
+ valueLabel->hide();
+ namesButton->hide();
+ namesLabel->hide();
+ valueExactButton->hide();
+ } else {
+ valueEdit->show();
+ valueLabel->show();
+ namesButton->show();
+ namesLabel->show();
+ valueExactButton->show();
+ }
+
+ if(v) {
+ //fill in original parameters
+ set_name_label_and_entry(v, nameEdit, namesLabel);
+ valueEdit->setText(get_value_string(v->get(), false, NULL));
+ nameEdit->setReadOnly(v->isBuiltin());
+ valueEdit->setReadOnly(v->isBuiltin());
+ valueExactButton->setEnabled(!v->isBuiltin());
+ categoryCombo->lineEdit()->setText(v->category().c_str());
+ titleEdit->setText(v->title(false).c_str());
+ valueExactButton->setChecked(!(*printops.is_approximate) && !v->isApproximate());
+ } else {
+ nameEdit->setReadOnly(false);
+ valueEdit->setReadOnly(false);
+ valueExactButton->setEnabled(true);
+
+ //fill in default values
+ nameEdit->setText(CALCULATOR->getName().c_str());
+ namesLabel->setText("");
+ if(initial_value && !force_value) valueEdit->setText(get_value_string(*initial_value));
+ else valueEdit->setText("");
+ categoryCombo->lineEdit()->setText(category);
+ titleEdit->setText("");
+ if(initial_value) valueExactButton->setChecked(!initial_value->isApproximate());
+ else valueExactButton->setChecked(true);
+ if(force_value) {
+ valueEdit->setReadOnly(true);
+ valueExactButton->setEnabled(false);
+ }
+ }
+
+ init_value = initial_value;
+ force_init_value = force_value;
+
+ if(exec() == QDialog::Accepted) {
+ v = edited_variable;
+ edited_variable = NULL;
+ return v;
+ }
+ edited_variable = NULL;
+ return NULL;
+}
+
+void QalculateEditVariableDialog::editNames() {
+ if(!names_edit_dialog) {
+ names_edit_dialog = new QalculateEditNamesDialog(TYPE_VARIABLE, this);
+ names_edit_dialog->setNames(edited_variable, nameEdit->text(), false);
+ } else {
+ names_edit_dialog->setNames(edited_variable, nameEdit->text(), true);
+ }
+ names_edit_dialog->exec();
+ names_edit_dialog->setNamesLE(nameEdit, namesLabel);
+}
+
+void QalculateEditVariableDialog::nameChanged(const QString &name) {
+ if(name.isNull()) return;
+ if(!CALCULATOR->variableNameIsValid(name.ascii())) {
+ nameEdit->blockSignals(true);
+ nameEdit->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str());
+ nameEdit->blockSignals(false);
+ }
+}
+
+#include "qalculateeditvariabledialog.moc"
+
diff --git a/src/qalculateeditvariabledialog.h b/src/qalculateeditvariabledialog.h
new file mode 100644
index 0000000..14ccd4d
--- /dev/null
+++ b/src/qalculateeditvariabledialog.h
@@ -0,0 +1,74 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEEDITVARIABLEDIALOG_H
+#define QALCULATEEDITVARIABLEDIALOG_H
+
+#include <kdialogbase.h>
+
+class QLabel;
+class KComboBox;
+class KLineEdit;
+class QCheckBox;
+class QPushButton;
+class MathStructure;
+class QalculateEditNamesDialog;
+class KnownVariable;
+class QGridLayout;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateEditVariableDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateEditVariableDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateEditVariableDialog();
+
+ KnownVariable *editVariable(QString category = QString::null, KnownVariable *v = NULL, MathStructure *initial_value = NULL, bool force_value = false);
+
+ QalculateEditNamesDialog *names_edit_dialog;
+ KnownVariable *edited_variable;
+ KComboBox *categoryCombo;
+ KLineEdit *valueEdit, *nameEdit, *titleEdit;
+ QLabel *namesLabel, *titleLabel, *nameLabel, *valueLabel;
+ QCheckBox *valueExactButton;
+ QPushButton *namesButton;
+
+private:
+
+ MathStructure *init_value;
+ bool force_init_value;
+
+public slots:
+
+ void editNames();
+ void nameChanged(const QString&);
+
+protected slots:
+
+ void slotHelp();
+ void slotOk();
+
+};
+
+#endif
diff --git a/src/qalculateexportcsvdialog.cpp b/src/qalculateexportcsvdialog.cpp
new file mode 100644
index 0000000..93022f5
--- /dev/null
+++ b/src/qalculateexportcsvdialog.cpp
@@ -0,0 +1,186 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateexportcsvdialog.h"
+#include "qalculate_kde_utils.h"
+
+#include <qlayout.h>
+#include <kurlrequester.h>
+#include <klineedit.h>
+#include <qlabel.h>
+#include <qradiobutton.h>
+#include <qpushbutton.h>
+#include <kcombobox.h>
+#include <qbuttongroup.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kapplication.h>
+
+extern MathStructure *mstruct;
+
+QalculateExportCSVDialog::QalculateExportCSVDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Export CSV File"), Ok | Cancel | Help, Ok, true) {
+
+ setMainWidget(new QWidget(this));
+ QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
+ QButtonGroup *group = new QButtonGroup();
+ currentResultButton = new QRadioButton(i18n("Current result"), mainWidget());
+ group->insert(currentResultButton, 0);
+ grid->addWidget(currentResultButton, 0, 0);
+ currentResultButton->setChecked(true);
+ matrixVectorButton = new QRadioButton(i18n("Matrix/vector variable"), mainWidget());
+ group->insert(matrixVectorButton, 1);
+ grid->addWidget(matrixVectorButton, 1, 0);
+ matrixVectorEdit = new KLineEdit(mainWidget());
+ grid->addWidget(matrixVectorEdit, 1, 1);
+ grid->addWidget(new QLabel(i18n("File:"), mainWidget()), 2, 0);
+ fileEdit = new KURLRequester(mainWidget());
+ fileEdit->setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly);
+ fileEdit->setCaption(i18n("Export CSV File"));
+ grid->addWidget(fileEdit, 2, 1);
+ grid->addWidget(new QLabel(i18n("Delimiter:"), mainWidget()), 3, 0);
+ delimiterCombo = new KComboBox(mainWidget());
+ delimiterCombo->setMaximumWidth(250);
+ delimiterCombo->insertItem(i18n("Comma"));
+ delimiterCombo->insertItem(i18n("Tabulator"));
+ delimiterCombo->insertItem(i18n("Semicolon"));
+ delimiterCombo->insertItem(i18n("Space"));
+ delimiterCombo->insertItem(i18n("Other"));
+ delimiterCombo->setEditable(false);
+ grid->addWidget(delimiterCombo, 3, 1);
+ otherDelimiterEdit = new KLineEdit(mainWidget());
+ grid->addWidget(otherDelimiterEdit, 4, 1);
+ otherDelimiterEdit->setEnabled(false);
+
+ connect(group, SIGNAL(clicked(int)), this, SLOT(exportSourceChanged(int)));
+ connect(delimiterCombo, SIGNAL(activated(int)), this, SLOT(delimiterChanged(int)));
+
+}
+
+QalculateExportCSVDialog::~QalculateExportCSVDialog() {}
+
+void QalculateExportCSVDialog::slotHelp() {
+ KApplication::kApplication()->invokeHelp("qalculate-import-export-csv");
+}
+
+void QalculateExportCSVDialog::exportSourceChanged(int i) {
+ matrixVectorEdit->setEnabled(i == 1);
+}
+void QalculateExportCSVDialog::delimiterChanged(int i) {
+ otherDelimiterEdit->setEnabled(i == 4);
+}
+void QalculateExportCSVDialog::slotOk() {
+
+ QString str = fileEdit->url().stripWhiteSpace();
+ if(str.isEmpty()) {
+ //no name -- open dialog again
+ fileEdit->setFocus();
+ KMessageBox::error(this, i18n("No file name entered."));
+ return;
+ }
+ string delimiter = "";
+ switch(delimiterCombo->currentItem()) {
+ case 0: {
+ delimiter = ",";
+ break;
+ }
+ case 1: {
+ delimiter = "\t";
+ break;
+ }
+ case 2: {
+ delimiter = ";";
+ break;
+ }
+ case 3: {
+ delimiter = " ";
+ break;
+ }
+ case 4: {
+ delimiter = otherDelimiterEdit->text().ascii();
+ break;
+ }
+ }
+ if(delimiter.empty()) {
+ //no delimiter -- open dialog again
+ otherDelimiterEdit->setFocus();
+ KMessageBox::error(this, i18n("No delimiter selected."));
+ return;
+ }
+ MathStructure *matrix_struct;
+ if(export_variable) {
+ matrix_struct = (MathStructure*) &export_variable->get();
+ } else if(currentResultButton->isChecked()) {
+ matrix_struct = mstruct;
+ } else {
+ string str2 = matrixVectorEdit->text().ascii();
+ remove_blank_ends(str2);
+ if(str2.empty()) {
+ matrixVectorEdit->setFocus();
+ KMessageBox::error(this, i18n("No variable name entered."));
+ return;
+ }
+ Variable *var = CALCULATOR->getActiveVariable(str2);
+ if(!var || !var->isKnown()) {
+ var = CALCULATOR->getVariable(str2);
+ while(var && !var->isKnown()) {
+ var = CALCULATOR->getVariable(str2);
+ }
+ }
+ if(!var || !var->isKnown()) {
+ matrixVectorEdit->setFocus();
+ KMessageBox::error(this, i18n("No known variable with entered name found."));
+ return;
+ }
+ matrix_struct = (MathStructure*) &((KnownVariable*) var)->get();
+ }
+ if(!CALCULATOR->exportCSV(*matrix_struct, str.ascii(), delimiter)) {
+ QString error_str;
+ error_str.sprintf(i18n("Could not export to file \n%s"), str.ascii());
+ KMessageBox::error(this, error_str);
+ reject();
+ }
+ accept();
+
+}
+
+void QalculateExportCSVDialog::exportCSVFile(KnownVariable *v) {
+
+ fileEdit->setFocus();
+
+ export_variable = v;
+
+ if(v) {
+ fileEdit->setURL(v->preferredDisplayName(false, false, false, false, &can_display_unicode_string_function, (void*) fileEdit->lineEdit()).name.c_str());
+ matrixVectorEdit->setText(v->preferredDisplayName(false, false, false, false, &can_display_unicode_string_function, (void*) matrixVectorEdit).name.c_str());
+ matrixVectorButton->setChecked(true);
+ } else {
+ fileEdit->clear();
+ matrixVectorEdit->clear();
+ currentResultButton->setChecked(true);
+ }
+ currentResultButton->setEnabled(v == NULL);
+ matrixVectorButton->setEnabled(v == NULL);
+ matrixVectorEdit->setEnabled(false);
+
+ exec();
+
+}
+
+
+#include "qalculateexportcsvdialog.moc"
diff --git a/src/qalculateexportcsvdialog.h b/src/qalculateexportcsvdialog.h
new file mode 100644
index 0000000..57e45f4
--- /dev/null
+++ b/src/qalculateexportcsvdialog.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEEXPORTCSVDIALOG_H
+#define QALCULATEEXPORTCSVDIALOG_H
+
+#include <kdialogbase.h>
+
+class KLineEdit;
+class KComboBox;
+class QRadioButton;
+class KURLRequester;
+class KnownVariable;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateExportCSVDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateExportCSVDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateExportCSVDialog();
+
+ KLineEdit *otherDelimiterEdit, *matrixVectorEdit;
+ KComboBox *delimiterCombo;
+ QRadioButton *currentResultButton, *matrixVectorButton;
+ KURLRequester *fileEdit;
+
+ void exportCSVFile(KnownVariable *v = NULL);
+
+private:
+
+ KnownVariable *export_variable;
+
+public slots:
+
+ void exportSourceChanged(int);
+ void delimiterChanged(int);
+
+protected slots:
+
+ void slotHelp();
+ void slotOk();
+
+};
+
+#endif
diff --git a/src/qalculateexpressionedit.cpp b/src/qalculateexpressionedit.cpp
new file mode 100644
index 0000000..6ef9328
--- /dev/null
+++ b/src/qalculateexpressionedit.cpp
@@ -0,0 +1,1018 @@
+/***************************************************************************
+ * Copyright (C) 2005. 2007 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateexpressionedit.h"
+
+#include "qalculate_kde_utils.h"
+#include "kqalculate.h"
+#include <kdeversion.h>
+#include <kcursor.h>
+#include <qstyle.h>
+#include <qpainter.h>
+#include <qapplication.h>
+#include <qfontmetrics.h>
+#include <kstringhandler.h>
+#include <kpopupmenu.h>
+#include <kxmlguifactory.h>
+#include <kxmlguiclient.h>
+#include <kaction.h>
+#include <klocale.h>
+#include <qsimplerichtext.h>
+
+extern vector<mode_struct> modes;
+
+extern KQalculate *mainWin;
+extern PrintOptions printops;
+extern EvaluationOptions evalops;
+extern bool rpn_mode, rpn_keypad_only;
+extern tree_struct function_cats, unit_cats, variable_cats;
+extern vector<void*> ia_units, ia_variables, ia_functions;
+
+class QalculateExpressionEditListBoxItem : public QListBoxItem {
+
+public:
+
+ QalculateExpressionEditListBoxItem(ExpressionItem *eitem);
+ virtual ~QalculateExpressionEditListBoxItem();
+
+ int height(const QListBox*) const;
+ int width(const QListBox*) const;
+
+ bool reuse(ExpressionItem *newItem);
+
+ ExpressionItem *item;
+
+protected:
+
+ void paint(QPainter*);
+
+private:
+
+ QString title;
+ int italic_index;
+ bool rich_text;
+
+};
+
+QalculateExpressionEdit::QalculateExpressionEdit(bool connected_to_main_win, QWidget *parent, const char *name) : KLineEdit(parent, name) {
+
+ qalculateCompletionBox = new QalculateExpressionEditCompletionBox(this);
+ qalculateCompletion = new KCompletion();
+ setCompletionObject(qalculateCompletion);
+
+ pos_before_completion = 0;
+
+ b_main = connected_to_main_win;
+
+ dont_change_index = false;
+ expression_history_index = -1;
+
+ setCompletionMode(KGlobalSettings::CompletionPopup);
+
+ setKeyCompression(false);
+
+ //check for position changes regularly
+ prev_position = 0;
+ pos_timer = startTimer(50);
+
+ connect(qalculateCompletionBox, SIGNAL(highlighted(QListBoxItem*)), this, SLOT(insertCompletion(QListBoxItem*)));
+ connect(qalculateCompletionBox, SIGNAL(userCancelled(const QString&)), this, SLOT(cancelCompletion(const QString&)));
+ connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&)));
+
+}
+
+QalculateExpressionEdit::~QalculateExpressionEdit() {}
+
+void QalculateExpressionEdit::timerEvent(QTimerEvent *event) {
+ if(event->timerId() == pos_timer) {
+ if(cursorPosition() != prev_position) {
+ prev_position = cursorPosition();
+ emit cursorMoved();
+ }
+ } else {
+ KLineEdit::timerEvent(event);
+ }
+}
+
+void QalculateExpressionEdit::onTextChanged(const QString &str) {
+ if(str.isEmpty()) {
+ if(qalculateCompletionBox) {
+ qalculateCompletionBox->hide();
+ qalculateCompletionBox->clear();
+ }
+ return;
+ }
+ prev_position = cursorPosition();
+}
+
+void QalculateExpressionEdit::cancelCompletion(const QString &str) {
+ int new_pos = pos_before_completion;
+ setText(str);
+ setCursorPosition(new_pos);
+}
+
+void QalculateExpressionEdit::enableCompletion() {
+ setCompletionMode(KGlobalSettings::CompletionPopup);
+}
+void QalculateExpressionEdit::disableCompletion() {
+ setCompletionMode(KGlobalSettings::CompletionNone);
+}
+bool QalculateExpressionEdit::completionEnabled() const {
+ return completionMode() == KGlobalSettings::CompletionPopup;
+}
+
+QPopupMenu *QalculateExpressionEdit::createPopupMenu() {
+
+ setCompletionObject(NULL);
+ QPopupMenu *menu = KLineEdit::createPopupMenu();
+ setCompletionObject(qalculateCompletion);
+ menu->insertSeparator();
+ if(completionMode() == KGlobalSettings::CompletionPopup) menu->insertItem(i18n("Disable Completion"), this, SLOT(disableCompletion()));
+ else menu->insertItem(i18n("Enable Completion"), this, SLOT(enableCompletion()));
+ if(b_main) {
+ menu->insertSeparator();
+ mainWin->ActionReadPrecision->plug(menu);
+ mainWin->ActionLimitImplicitMultiplication->plug(menu);
+ mainWin->ActionRPNMode->plug(menu);
+ QPopupMenu *modes_menu = new QPopupMenu(menu);
+ QObject::connect(modes_menu, SIGNAL(activated(int)), mainWin, SLOT(loadMode(int)));
+ for(size_t i = 0; i < modes.size(); i++) {
+ modes_menu->insertItem(modes[i].name, i, i);
+ }
+ modes_menu->insertSeparator();
+ mainWin->ActionSaveModeAs->plug(modes_menu);
+ mainWin->ActionDeleteMode->plug(modes_menu);
+ menu->insertItem(i18n("Meta Modes"), modes_menu);
+ menu->insertSeparator();
+ mainWin->ActionInsertMatrix->plug(menu);
+ mainWin->ActionInsertVector->plug(menu);
+ }
+ return menu;
+
+}
+
+#if QT_VERSION >= 0x030200
+#define GET_SELECTION int start = selectionStart(), end = -1; if(start >= 0) end = start + selectedText().length();
+#else
+#define GET_SELECTION int start = -1, end = -1; getSelection(&start, &end);
+#endif
+#define RESTORE_SELECTION if(start > 0) setSelection(start, end - start);
+
+void QalculateExpressionEdit::addToHistory(const QString &str) {
+ for(QStringList::Iterator it = expression_history.begin(); it != expression_history.end(); ++it) {
+ if(*it == str) {
+ expression_history.erase(it);
+ break;
+ }
+ }
+ if(expression_history.size() >= 25) {
+ expression_history.pop_back();
+ }
+ expression_history.insert(expression_history.begin(), str);
+ expression_history_index = 0;
+}
+
+
+void QalculateExpressionEdit::setAfterCompletionPosition() {
+ setCursorPosition(cpos_ac);
+}
+
+void QalculateExpressionEdit::insertCompletion(QListBoxItem *li) {
+
+ ExpressionItem *item = ((QalculateExpressionEditListBoxItem*) li)->item;
+
+ setSelection(cstart, cend - cstart + 1);
+
+ QString str = completed_text;
+ const ExpressionName *ename = NULL, *ename_r = NULL;
+ ename_r = &item->preferredInputName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) this);
+ for(size_t name_i = 0; name_i <= item->countNames() && !ename; name_i++) {
+ if(name_i == 0) {
+ ename = ename_r;
+ } else {
+ ename = &item->getName(name_i);
+ if(!ename || ename == ename_r || ename->plural || (ename->unicode && (!printops.use_unicode_signs || !can_display_unicode_string_function(ename->name.c_str(), (void*) this)))) {
+ ename = NULL;
+ }
+ }
+ if(ename) {
+ if(str.length() <= ename->name.length()) {
+ for(size_t i = 0; i < str.length(); i++) {
+ if(ename->name[i] != str[i]) {
+ ename = NULL;
+ break;
+ }
+ }
+ } else {
+ ename = NULL;
+ }
+ }
+ }
+ for(size_t name_i = 1; name_i <= item->countNames() && !ename; name_i++) {
+ ename = &item->getName(name_i);
+ if(!ename || ename == ename_r || (!ename->plural && !(ename->unicode && (!printops.use_unicode_signs || !can_display_unicode_string_function(ename->name.c_str(), (void*) this))))) {
+ ename = NULL;
+ }
+ if(ename) {
+ if(str.length() <= ename->name.length()) {
+ for(size_t i = 0; i < str.length(); i++) {
+ if(ename->name[i] != str[i]) {
+ ename = NULL;
+ break;
+ }
+ }
+ } else {
+ ename = NULL;
+ }
+ }
+ }
+ if(!ename) ename = ename_r;
+ if(!ename) return;
+ if(item->type() == TYPE_FUNCTION) {
+ if(text()[cend + 1] == '(') {
+ insert(ename->name.c_str());
+ cend = cstart + ename->name.length() - 1;
+ cpos_ac = cend + 2;
+ } else {
+ str = ename->name.c_str();
+ str += "()";
+ insert(str);
+ cend = cstart + str.length() - 1;
+ cpos_ac = cend;
+ }
+ } else {
+ insert(ename->name.c_str());
+ cend = cstart + ename->name.length() - 1;
+ cpos_ac = cend + 1;
+ }
+ setCursorPosition(cpos_ac);
+
+}
+
+bool matchesExpressionItem(const QString &str, ExpressionItem *item) {
+ bool b_match = false;
+ for(size_t name_i = 1; !b_match && name_i <= item->countNames(); name_i++) {
+ const ExpressionName *ename = &item->getName(name_i);
+ if(ename && str.length() <= ename->name.length()) {
+ b_match = true;
+ for(size_t i = 0; i < str.length(); i++) {
+ if(ename->name[i] != str[i]) {
+ b_match = false;
+ break;
+ }
+ }
+ }
+ }
+ return b_match;
+}
+
+void QalculateExpressionEdit::makeCompletion(const QString &str) {
+ if(cursorPosition() <= 0 || str.isEmpty()) {
+ if(qalculateCompletionBox) {
+ qalculateCompletionBox->hide();
+ qalculateCompletionBox->clear();
+ }
+ return;
+ }
+ uint start = (uint) cursorPosition();
+ cend = (int) start - 1;
+ QString str2 = str;
+ str2.truncate(start);
+ const char *cstr = str2.ascii();
+ bool non_number_before = false;
+ size_t cpos = strlen(cstr) - 1;
+ start--;
+ while(true) {
+ while(cpos > 0 && (unsigned char) cstr[cpos] >= 0x80 && (unsigned char) cstr[cpos] <= 0xBF) {
+ cpos--;
+ }
+ if(!CALCULATOR->utf8_pos_is_valid_in_name((char*) &cstr[cpos])) {
+ start++;
+ break;
+ } else if(is_in(NUMBERS, cstr[cpos])) {
+ if(non_number_before) {
+ start++;
+ break;
+ }
+ } else {
+ non_number_before = true;
+ }
+ if(start == 0 || cpos == 0) break;
+ start--;
+ cpos--;
+ }
+ if(start >= (uint) cursorPosition()) {
+ if(qalculateCompletionBox) {
+ qalculateCompletionBox->hide();
+ qalculateCompletionBox->clear();
+ }
+ return;
+ }
+ cstart = (int) start;
+ str2.remove(0, start);
+
+ completed_text = str2;
+ pos_before_completion = cursorPosition();
+ qalculateCompletionBox->setCancelledText(text());
+
+ matched_items.clear();
+ if(evalops.parse_options.functions_enabled) {
+ for(size_t i = 0; i < CALCULATOR->functions.size(); i++) {
+ if(CALCULATOR->functions[i]->isActive()) {
+ if(matchesExpressionItem(str2, CALCULATOR->functions[i])) {
+ matched_items.push_back(CALCULATOR->functions[i]);
+ }
+ }
+ }
+ }
+ if(evalops.parse_options.variables_enabled) {
+ for(size_t i = 0; i < CALCULATOR->variables.size(); i++) {
+ if(CALCULATOR->variables[i]->isActive()) {
+ if(matchesExpressionItem(str2, CALCULATOR->variables[i])) {
+ matched_items.push_back(CALCULATOR->variables[i]);
+ }
+ }
+ }
+ }
+ if(evalops.parse_options.units_enabled) {
+ for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
+ if(CALCULATOR->units[i]->isActive() && CALCULATOR->units[i]->subtype() != SUBTYPE_COMPOSITE_UNIT) {
+ if(matchesExpressionItem(str2, CALCULATOR->units[i])) {
+ matched_items.push_back(CALCULATOR->units[i]);
+ }
+ }
+ }
+ }
+
+ if(matched_items.isEmpty()) {
+ if(qalculateCompletionBox) {
+ qalculateCompletionBox->hide();
+ qalculateCompletionBox->clear();
+ }
+ } else {
+ setCompletedItems();
+ }
+}
+
+void QalculateExpressionEdit::updateCompletion() {
+}
+
+void QalculateExpressionEdit::wrapSelection() {
+ GET_SELECTION
+ if(start >= 0) {
+ deselect();
+ setCursorPosition(start);
+ insert("(");
+ setCursorPosition(end + 1);
+ insert(")");
+ setSelection(start, end - start + 2);
+ }
+}
+
+void QalculateExpressionEdit::keyPressEvent(QKeyEvent *e) {
+ if(e->key() == Key_Enter || e->key() == Key_Return) {
+ if(b_main) {
+ mainWin->execute();
+ e->accept();
+ return;
+ } else {
+ return KLineEdit::keyPressEvent(e);
+ }
+ }
+ if(e->state() & ControlButton && e->key() == Key_Asterisk) {
+ if(rpn_mode && b_main && (!rpn_keypad_only || e->state() & Keypad)) {
+ mainWin->calculateRPN(OPERATION_RAISE);
+ return;
+ }
+ insert("^");
+ e->accept();
+ return;
+ }
+ if(e->state() != 0 && e->state() != ShiftButton && e->state() != Keypad) {
+ KLineEdit::keyPressEvent(e);
+ return;
+ }
+ switch(e->key()) {
+ case Key_Period: {
+ if(e->state() == Keypad) {
+ insert(CALCULATOR->getDecimalPoint());
+ e->accept();
+ return;
+ }
+ break;
+ }
+ case Key_Comma: {
+ if(e->state() == Keypad) {
+ insert(CALCULATOR->getDecimalPoint());
+ e->accept();
+ return;
+ }
+ break;
+ }
+ case Key_AsciiCircum: {
+ if(rpn_mode && b_main && (!rpn_keypad_only || e->state() & Keypad)) {
+ mainWin->calculateRPN(OPERATION_RAISE);
+ return;
+ }
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ insert("^");
+ e->accept();
+ return;
+ }
+ case Key_Slash: {
+ if(rpn_mode && b_main && (!rpn_keypad_only || e->state() & Keypad)) {
+ mainWin->calculateRPN(OPERATION_DIVIDE);
+ return;
+ }
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ if(printops.use_unicode_signs && printops.division_sign == DIVISION_SIGN_DIVISION && can_display_unicode_string_function(SIGN_DIVISION, (void*) this)) {
+ insert(SIGN_DIVISION);
+ e->accept();
+ return;
+ }
+ break;
+ }
+ case Key_Asterisk: {
+ if(rpn_mode && b_main && (!rpn_keypad_only || e->state() & Keypad)) {
+ mainWin->calculateRPN(OPERATION_MULTIPLY);
+ return;
+ }
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_DOT && can_display_unicode_string_function(SIGN_MULTIDOT, (void*) this)) {
+ insert(SIGN_MULTIDOT);
+ } else if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_DOT && can_display_unicode_string_function(SIGN_SMALLCIRCLE, (void*) this)) {
+ insert(SIGN_SMALLCIRCLE);
+ } else if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_X && can_display_unicode_string_function(SIGN_MULTIPLICATION, (void*) this)) {
+ insert(SIGN_MULTIPLICATION);
+ } else {
+ insert("*");
+ }
+ e->accept();
+ return;
+ }
+ case Key_Plus: {
+ if(rpn_mode && b_main && (!rpn_keypad_only || e->state() & Keypad)) {
+ mainWin->calculateRPN(OPERATION_ADD);
+ return;
+ }
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ e->accept();
+ break;
+ }
+ case Key_Minus: {
+ if(rpn_mode && b_main && (!rpn_keypad_only || e->state() & Keypad)) {
+ mainWin->calculateRPN(OPERATION_SUBTRACT);
+ return;
+ }
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_MINUS, (void*) this)) {
+ insert(SIGN_MINUS);
+ e->accept();
+ return;
+ }
+ break;
+ }
+ case Key_Up: {}
+ case Key_PageUp: {
+ if(expression_history_index + 1 < (int) expression_history.size()) {
+ expression_history_index++;
+ dont_change_index = true;
+ setText(expression_history[expression_history_index]);
+ dont_change_index = false;
+ }
+ e->accept();
+ return;
+ }
+ case Key_Down: {}
+ case Key_PageDown: {
+ if(expression_history_index > -1) {
+ expression_history_index--;
+ dont_change_index = true;
+ if(expression_history_index < 0) {
+ clear();
+ } else {
+ setText(expression_history[expression_history_index]);
+ }
+ dont_change_index = false;
+ }
+ e->accept();
+ return;
+ }
+ case Key_BraceLeft: {}
+ case Key_BraceRight: {
+ return;
+ }
+ case 0xffff: {
+ if(e->text().utf8() == "⁰") {
+ insert("°");
+ e->accept();
+ return;
+ }
+ if(e->text().utf8() == "¹") {
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ insert("^1");
+ e->accept();
+ return;
+ }
+ if(e->text().utf8() == "²") {
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ insert("^2");
+ e->accept();
+ return;
+ }
+ if(e->text().utf8() == "³") {
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ insert("^3");
+ e->accept();
+ return;
+ }
+ if(e->text().utf8() == "⁴") {
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ insert("^4");
+ e->accept();
+ return;
+ }
+ if(e->text().utf8() == "⁵") {
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ insert("^5");
+ e->accept();
+ return;
+ }
+ if(e->text().utf8() == "⁶") {
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ insert("^6");
+ e->accept();
+ return;
+ }
+ if(e->text().utf8() == "⁷") {
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ insert("^7");
+ e->accept();
+ return;
+ }
+ if(e->text().utf8() == "⁸") {
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ insert("^8");
+ e->accept();
+ return;
+ }
+ if(e->text().utf8() == "⁹") {
+ if(!evalops.parse_options.rpn) {
+ wrapSelection();
+ deselect();
+ }
+ insert("^9");
+ e->accept();
+ return;
+ }
+ break;
+ }
+ }
+ KLineEdit::keyPressEvent(e);
+}
+
+bool QalculateExpressionEdit::eventFilter(QObject *o, QEvent *ev) {
+ if(o == this && ev->type() == QEvent::KeyPress) {
+ QKeyEvent *e = static_cast<QKeyEvent *>(ev);
+ if((e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) && qalculateCompletionBox && qalculateCompletionBox->isVisible()) {
+ if(qalculateCompletionBox->selectedItem()) {
+ KCursor::autoHideEventFilter(this, ev);
+ e->accept();
+ qalculateCompletionBox->hide();
+ deselect();
+ return true;
+ } else {
+ qalculateCompletionBox->hide();
+ return false;
+ }
+ }
+ }
+ return KLineEdit::eventFilter(o, ev);
+}
+
+
+void set_title(ExpressionItem *item, QString &title) {
+ if(item->type() != TYPE_VARIABLE || !item->title(false).empty()) {
+ title = item->title().c_str();
+ } else {
+ Variable *v = (Variable*) item;
+ if(is_answer_variable(v)) {
+ title = i18n("a previous result");
+ } else if(v->isKnown()) {
+ if(((KnownVariable*) v)->isExpression()) {
+ title = CALCULATOR->localizeExpression(((KnownVariable*) v)->expression()).c_str();
+ } else {
+ if(((KnownVariable*) v)->get().isMatrix()) {
+ title = i18n("matrix");
+ } else if(((KnownVariable*) v)->get().isVector()) {
+ title = i18n("vector");
+ } else {
+ title = CALCULATOR->printMathStructureTimeOut(((KnownVariable*) v)->get(), 30).c_str();
+ }
+ }
+ } else {
+ if(((UnknownVariable*) v)->assumptions()) {
+ switch(((UnknownVariable*) v)->assumptions()->sign()) {
+ case ASSUMPTION_SIGN_POSITIVE: {
+ title = i18n("positive");
+ break;
+ }
+ case ASSUMPTION_SIGN_NONPOSITIVE: {
+ title = i18n("non-positive");
+ break;
+ }
+ case ASSUMPTION_SIGN_NEGATIVE: {
+ title = i18n("negative");
+ break;
+ }
+ case ASSUMPTION_SIGN_NONNEGATIVE: {
+ title = i18n("non-negative");
+ break;
+ }
+ case ASSUMPTION_SIGN_NONZERO: {
+ title = i18n("non-zero");
+ break;
+ }
+ default: {}
+ }
+ if(!title.isEmpty() && !((UnknownVariable*) v)->assumptions()->type() == ASSUMPTION_TYPE_NONE) title += " ";
+ switch(((UnknownVariable*) v)->assumptions()->type()) {
+ case ASSUMPTION_TYPE_INTEGER: {
+ title += i18n("integer");
+ break;
+ }
+ case ASSUMPTION_TYPE_RATIONAL: {
+ title += i18n("rational");
+ break;
+ }
+ case ASSUMPTION_TYPE_REAL: {
+ title += i18n("real");
+ break;
+ }
+ case ASSUMPTION_TYPE_COMPLEX: {
+ title += i18n("complex");
+ break;
+ }
+ case ASSUMPTION_TYPE_NUMBER: {
+ title += i18n("number");
+ break;
+ }
+ case ASSUMPTION_TYPE_NONMATRIX: {
+ title += i18n("(not matrix)");
+ break;
+ }
+ default: {}
+ }
+ if(title.isEmpty()) title = i18n("unknown");
+ } else {
+ title = i18n("default assumptions");
+ }
+ }
+ }
+}
+
+string sub_suffix(const ExpressionName *ename) {
+ size_t i = ename->name.rfind('_');
+ bool b = i == string::npos || i == ename->name.length() - 1 || i == 0;
+ size_t i2 = 1;
+ string str;
+ if(b) {
+ if(is_in(NUMBERS, ename->name[ename->name.length() - 1])) {
+ while(ename->name.length() > i2 + 1 && is_in(NUMBERS, ename->name[ename->name.length() - 1 - i2])) {
+ i2++;
+ }
+ }
+ str += ename->name.substr(0, ename->name.length() - i2);
+ } else {
+ str += ename->name.substr(0, i);
+ }
+ str += "<sub>";
+ if(b) str += ename->name.substr(ename->name.length() - i2, i2);
+ else str += ename->name.substr(i + 1, ename->name.length() - (i + 1));
+ str += "</sub>";
+ return str;
+}
+
+QString makeListName(ExpressionItem *item, QWidget *w, int *italic_index, bool *rich_text) {
+ string str;
+ const ExpressionName *ename, *ename_r;
+ *rich_text = false;
+ bool b = false;
+ ename_r = &item->preferredInputName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) w);
+ if(ename_r->suffix && ename_r->name.length() > 1) {
+ str = sub_suffix(ename_r);
+ *rich_text = true;
+ } else {
+ str = ename_r->name;
+ }
+ if(item->type() == TYPE_FUNCTION) str += "()";
+ for(size_t name_i = 1; name_i <= item->countNames(); name_i++) {
+ ename = &item->getName(name_i);
+ if(ename && ename != ename_r && !ename->plural && (!ename->unicode || can_display_unicode_string_function(ename->name.c_str(), (void*) w))) {
+ str += " ";
+ if(!b) {
+ *italic_index = str.length();
+ *rich_text = true;
+ str += "<i>";
+ b = true;
+ }
+ if(ename->suffix && ename->name.length() > 1) {
+ str += sub_suffix(ename);
+ } else {
+ str += ename->name;
+ }
+ if(item->type() == TYPE_FUNCTION) str += "()";
+ }
+ }
+ if(b) str += "</i>";
+ return str.c_str();
+}
+
+QalculateExpressionEditListBoxItem::QalculateExpressionEditListBoxItem(ExpressionItem *eitem) : QListBoxItem() {
+ item = eitem;
+ italic_index = -1;
+ setText(makeListName(item, listBox(), &italic_index, &rich_text));
+ set_title(item, title);
+}
+QalculateExpressionEditListBoxItem::~QalculateExpressionEditListBoxItem() {
+}
+
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+QString rPixelSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxPixels)
+{
+ uint nameWidth = fontMetrics.width(name);
+
+ if (maxPixels < nameWidth)
+ {
+ QString tmp = name;
+ const uint em = fontMetrics.maxWidth();
+ maxPixels -= fontMetrics.width("...");
+
+ while (maxPixels < nameWidth && !tmp.isEmpty())
+ {
+ int length = tmp.length();
+ int delta = em ? (nameWidth - maxPixels) / em : length;
+
+ if(delta < 1) delta = 1;
+ else if(length < delta) delta = length;
+
+ tmp.remove(length - delta, delta);
+ nameWidth = fontMetrics.width(tmp);
+ }
+
+ return (tmp + "...");
+ }
+
+ return name;
+}
+#endif
+
+void QalculateExpressionEditListBoxItem::paint(QPainter *painter) {
+
+ int itemHeight = height(listBox());
+
+ int entryWidth = listBox()->width() - listBox()->style().pixelMetric(QStyle::PM_ScrollBarExtent) - 2 * listBox()->style().pixelMetric(QStyle::PM_DefaultFrameWidth);
+ int titleWidth = (entryWidth / 2) - 1;
+ int nameWidth = entryWidth - titleWidth - 2;
+
+ if(!text().isEmpty()) {
+ QString squeezedText;
+ if(rich_text) {
+ QSimpleRichText rt(text(), painter->font());
+ rt.setWidth(entryWidth);
+ if(rt.widthUsed() > nameWidth - 1) {
+ squeezedText = text();
+ if(italic_index > 0) squeezedText.truncate(italic_index);
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ squeezedText = rPixelSqueeze(squeezedText, listBox()->fontMetrics(), nameWidth);
+#else
+ squeezedText = KStringHandler::rPixelSqueeze(squeezedText, listBox()->fontMetrics(), nameWidth);
+#endif
+ painter->drawText(0, 0, nameWidth, itemHeight, Qt::AlignLeft | Qt::AlignVCenter, squeezedText);
+ } else {
+ QColorGroup cg = listBox()->colorGroup();
+ cg.setColor(QColorGroup::Text, painter->pen().color());
+ rt.draw(painter, 1, 0, QRect(0, 0, nameWidth - 1, itemHeight), cg, &painter->brush());
+ }
+ } else {
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ squeezedText = rPixelSqueeze(text(), listBox()->fontMetrics(), nameWidth);
+#else
+ squeezedText = KStringHandler::rPixelSqueeze(text(), listBox()->fontMetrics(), nameWidth);
+#endif
+ painter->drawText(0, 0, nameWidth, itemHeight, Qt::AlignLeft | Qt::AlignVCenter, squeezedText);
+ }
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ squeezedText = rPixelSqueeze(title, listBox()->fontMetrics(), titleWidth);
+#else
+ squeezedText = KStringHandler::rPixelSqueeze(title, listBox()->fontMetrics(), titleWidth);
+#endif
+ QFont font = painter->font();
+ font.setItalic(true);
+ painter->setFont(font);
+ painter->drawText(entryWidth - titleWidth, 0, titleWidth, itemHeight, Qt::AlignLeft | Qt::AlignVCenter, squeezedText);
+ }
+
+}
+
+int QalculateExpressionEditListBoxItem::height(const QListBox *lb) const {
+ int h;
+ h = lb->fontMetrics().lineSpacing() + 4;
+ return QMAX(h, QApplication::globalStrut().height());
+}
+
+int QalculateExpressionEditListBoxItem::width(const QListBox *lb) const {
+ return QMAX(lb->fontMetrics().width(text()) + 6, QApplication::globalStrut().width());
+}
+bool QalculateExpressionEditListBoxItem::reuse(ExpressionItem *newItem) {
+ if(item == newItem) return false;
+ item = newItem;
+ italic_index = -1;
+ setText(makeListName(item, listBox(), &italic_index, &rich_text));
+ set_title(item, title);
+ return true;
+}
+
+QalculateExpressionEditCompletionBox::QalculateExpressionEditCompletionBox(QWidget *parent, const char *name) : KCompletionBox(parent, name) {
+}
+QalculateExpressionEditCompletionBox::~QalculateExpressionEditCompletionBox() {
+}
+
+void QalculateExpressionEditCompletionBox::setItems(const QValueVector<ExpressionItem*>& items) {
+
+ bool block = signalsBlocked();
+ blockSignals(true);
+
+ QListBoxItem* item = firstItem();
+ if(!item) {
+ insertItemList(items);
+ } else {
+ //Keep track of whether we need to change anything,
+ //so we can avoid a repaint for identical updates,
+ //to reduce flicker
+ bool dirty = false;
+
+#if QT_VERSION >= 0x030200
+ QValueVector<ExpressionItem*>::ConstIterator it = items.constBegin();
+ const QValueVector<ExpressionItem*>::ConstIterator itEnd = items.constEnd();
+#else
+ QValueVector<ExpressionItem*>::ConstIterator it = items.begin();
+ const QValueVector<ExpressionItem*>::ConstIterator itEnd = items.end();
+#endif
+
+ for (; it != itEnd; ++it) {
+ if(item) {
+ const bool changed = ((QalculateExpressionEditListBoxItem*) item)->reuse(*it);
+ dirty = dirty || changed;
+ item = item->next();
+ } else {
+ dirty = true;
+ //Inserting an item is a way of making this dirty
+ insertItem(new QalculateExpressionEditListBoxItem(*it));
+ }
+ }
+
+ //If there is an unused item, mark as dirty -> less items now
+ if(item) dirty = true;
+
+ QListBoxItem* tmp = item;
+ while((item = tmp)) {
+ tmp = item->next();
+ delete item;
+ }
+
+ if(dirty) triggerUpdate(false);
+ }
+ sort();
+
+ if(isVisible() && size().height() != sizeHint().height()) {
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ hide();
+ popup();
+#else
+ sizeAndPosition();
+#endif
+ }
+
+ blockSignals(block);
+
+ // Trigger d->down_workaround = true within KCompletionBox
+ QStringList dummy;
+ KCompletionBox::insertItems(dummy, 1);
+
+}
+
+void QalculateExpressionEditCompletionBox::insertItemList(const QValueVector<ExpressionItem*> & list, int index) {
+ if(index < 0) index = count();
+ for(QValueVector<ExpressionItem*>::ConstIterator it = list.begin(); it != list.end(); ++it) {
+ insertItem(new QalculateExpressionEditListBoxItem(*it), index++);
+ }
+}
+
+void QalculateExpressionEdit::setCompletedItems() {
+
+ QString txt;
+ if(qalculateCompletionBox && qalculateCompletionBox->isVisible()) {
+ // The popup is visible already - do the matching on the initial string,
+ // not on the currently selected one.
+ txt = qalculateCompletionBox->cancelledText();
+ } else {
+ txt = text();
+ }
+
+ if(!matched_items.isEmpty() && !(matched_items.size() == 1 && matched_items[0]->hasName(txt.ascii()))) {
+
+ if(qalculateCompletionBox->isVisible()) {
+ bool wasSelected = qalculateCompletionBox->isSelected(qalculateCompletionBox->currentItem());
+ const QString currentSelection = qalculateCompletionBox->currentText();
+ qalculateCompletionBox->setItems(matched_items);
+ QListBoxItem* item = qalculateCompletionBox->findItem(currentSelection, Qt::ExactMatch);
+ // If no item is selected, that means the listbox hasn't been manipulated by the user yet,
+ // because it's not possible otherwise to have no selected item. In such case make
+ // always the first item current and unselected, so that the current item doesn't jump.
+ if(!item || !wasSelected) {
+ wasSelected = false;
+ item = qalculateCompletionBox->item(0);
+ }
+ if(item) {
+ qalculateCompletionBox->blockSignals(true);
+ qalculateCompletionBox->setCurrentItem(item);
+ qalculateCompletionBox->setSelected(item, wasSelected);
+ qalculateCompletionBox->blockSignals(false);
+ }
+ } else { // completion box not visible yet -> show it
+ if(!txt.isEmpty()) qalculateCompletionBox->setCancelledText(txt);
+ ((QalculateExpressionEditCompletionBox*) qalculateCompletionBox)->setItems(matched_items);
+ qalculateCompletionBox->popup();
+ }
+
+ } else {
+
+ if(qalculateCompletionBox && qalculateCompletionBox->isVisible()) {
+ qalculateCompletionBox->hide();
+ }
+
+ }
+
+}
+
+void QalculateExpressionEditCompletionBox::hideEvent(QHideEvent*) {
+ emit hidden();
+}
+
+#include "qalculateexpressionedit.moc"
diff --git a/src/qalculateexpressionedit.h b/src/qalculateexpressionedit.h
new file mode 100644
index 0000000..7434489
--- /dev/null
+++ b/src/qalculateexpressionedit.h
@@ -0,0 +1,109 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEEXPRESSIONEDIT_H
+#define QALCULATEEXPRESSIONEDIT_H
+
+#include <klineedit.h>
+#include <kcompletionbox.h>
+#include <kcompletion.h>
+#include <qvaluevector.h>
+
+class QStringList;
+class QPopupMenu;
+class QalculateExpressionEditCompletionBox;
+class ExpressionItem;
+class QListBoxItem;
+
+class QalculateExpressionEdit : public KLineEdit {
+
+ Q_OBJECT
+
+public:
+
+ QalculateExpressionEdit(bool connected_to_main_win, QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateExpressionEdit();
+
+ QValueVector<ExpressionItem*> matched_items;
+
+ bool b_main;
+ QStringList expression_history;
+ int expression_history_index;
+ bool dont_change_index;
+ QalculateExpressionEditCompletionBox *qalculateCompletionBox;
+ KCompletion *qalculateCompletion;
+
+ virtual bool eventFilter(QObject *o, QEvent *ev);
+ void keyPressEvent(QKeyEvent *e);
+
+public slots:
+
+ void onTextChanged(const QString&);
+ void addToHistory(const QString&);
+ void wrapSelection();
+ void makeCompletion(const QString&);
+ void insertCompletion(QListBoxItem *li);
+ void updateCompletion();
+ void setAfterCompletionPosition();
+ void cancelCompletion(const QString &str);
+ void setCompletedItems();
+ void enableCompletion();
+ void disableCompletion();
+ bool completionEnabled() const;
+
+signals:
+
+ void cursorMoved();
+
+protected:
+
+ virtual QPopupMenu *createPopupMenu();
+ virtual void timerEvent(QTimerEvent*);
+ int cstart, cend, cpos_ac, prev_position, pos_timer;
+ QString completed_text;
+ int pos_before_completion;
+
+};
+
+class QalculateExpressionEditCompletionBox : public KCompletionBox {
+
+ Q_OBJECT
+
+public:
+
+ QalculateExpressionEditCompletionBox(QWidget *parent, const char *name = 0);
+ virtual ~QalculateExpressionEditCompletionBox();
+ void insertItemList(const QValueVector<ExpressionItem*>& list, int index = -1);
+
+public slots:
+
+ void setItems(const QValueVector<ExpressionItem*>& items);
+
+protected:
+
+ void hideEvent(QHideEvent*);
+
+signals:
+
+ void hidden();
+
+};
+
+
+#endif
diff --git a/src/qalculatefunctionsdialog.cpp b/src/qalculatefunctionsdialog.cpp
new file mode 100644
index 0000000..80b452d
--- /dev/null
+++ b/src/qalculatefunctionsdialog.cpp
@@ -0,0 +1,537 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculatefunctionsdialog.h"
+#include "qalculate_kde_utils.h"
+#include "qalculateeditfunctiondialog.h"
+#include <kpushbutton.h>
+#include <qsplitter.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <klistview.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <qlayout.h>
+#include <ktextbrowser.h>
+#include <kapplication.h>
+#include <kstdguiitem.h>
+
+extern tree_struct function_cats;
+extern vector<void*> ia_functions;
+extern PrintOptions printops;
+
+QalculateFunctionsDialog::QalculateFunctionsDialog(QWidget *parent, const char *name) : KDialog(parent, name, false) {
+
+ function_edit_dialog = NULL;
+ selected_category = "";
+ selected_function = NULL;
+
+ QHBoxLayout *layout = new QHBoxLayout(this, marginHint(), spacingHint());
+
+ setCaption(i18n("Functions"));
+
+ QVBoxLayout *leftLayout = new QVBoxLayout(layout, spacingHint());
+
+ QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
+ leftLayout->addWidget(splitter);
+
+ categoryView = new KListView(splitter);
+ categoryView->addColumn(i18n("Category"));
+ categoryView->setRootIsDecorated(false);
+
+ functionView = new KListView(splitter);
+ functionView->addColumn(i18n("Function Name"));
+ functionView->setRootIsDecorated(false);
+
+ descriptionBrowser = new KTextBrowser(this);
+ leftLayout->addWidget(descriptionBrowser);
+
+ QVBoxLayout *buttonLayout = new QVBoxLayout(layout, spacingHint());
+
+ newButton = new QPushButton(i18n("New"), this);
+ buttonLayout->addWidget(newButton);
+ editButton = new QPushButton(i18n("Edit"), this);
+ editButton->setEnabled(false);
+ buttonLayout->addWidget(editButton);
+ deleteButton = new QPushButton(i18n("Delete"), this);
+ deleteButton->setEnabled(false);
+ buttonLayout->addWidget(deleteButton);
+ deactivateButton = new QPushButton(i18n("Deactivate"), this);
+ deactivateButton->setEnabled(false);
+ buttonLayout->addWidget(deactivateButton);
+ insertButton = new QPushButton(i18n("Insert"), this);
+ insertButton->setEnabled(false);
+ buttonLayout->addWidget(insertButton);
+ applyButton = new QPushButton(i18n("Apply"), this);
+ applyButton->setEnabled(false);
+ buttonLayout->addWidget(applyButton);
+ buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
+ helpButton = new KPushButton(KStdGuiItem::help(), this);
+ buttonLayout->addWidget(helpButton);
+ buttonClose = new KPushButton(KStdGuiItem::close(), this);
+ buttonClose->setFocus();
+ buttonLayout->addWidget(buttonClose);
+
+ resize(QSize(675, 475).expandedTo(size()));
+
+ connect(buttonClose, SIGNAL(clicked()), this, SLOT(close()));
+ connect(newButton, SIGNAL(clicked()), this, SLOT(newFunction()));
+ connect(editButton, SIGNAL(clicked()), this, SLOT(editFunction()));
+ connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteFunction()));
+ connect(deactivateButton, SIGNAL(clicked()), this, SLOT(deactivateFunction()));
+ connect(insertButton, SIGNAL(clicked()), this, SLOT(insertFunction()));
+ connect(applyButton, SIGNAL(clicked()), this, SLOT(applyFunction()));
+ connect(functionView, SIGNAL(selectionChanged()), this, SLOT(functionSelected()));
+ connect(functionView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(functionDoubleClicked(QListViewItem*)));
+ connect(categoryView, SIGNAL(selectionChanged()), this, SLOT(categorySelected()));
+ connect(helpButton, SIGNAL(clicked()), this, SLOT(slotHelp()));
+
+}
+
+QalculateFunctionsDialog::~QalculateFunctionsDialog() {
+}
+
+void QalculateFunctionsDialog::slotHelp() {
+ KApplication::kApplication()->invokeHelp("qalculate-managers");
+}
+
+void QalculateFunctionsDialog::updateFunctionTree() {
+ functionItems.clear();
+ categoryItems.clear();
+ categoryView->clear();
+ QListViewItem *i = new KListViewItem(categoryView, i18n("All")), *i2;
+ categoryItems[i] = i18n("All");
+ i->setOpen(true);
+ QString str;
+ tree_struct *item, *item2;
+ function_cats.it = function_cats.items.begin();
+ if(function_cats.it != function_cats.items.end()) {
+ item = &*function_cats.it;
+ ++function_cats.it;
+ item->it = item->items.begin();
+ } else {
+ item = NULL;
+ }
+ str = "";
+ i2 = i;
+ while(item) {
+ str += "/";
+ str += item->item.c_str();
+ i = new KListViewItem(i2, item->item.c_str());
+ i->setOpen(false);
+ categoryItems[i] = str;
+ if(str == selected_category) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ while(item && item->it == item->items.end()) {
+ int str_i = str.findRev("/");
+ if(str_i < 0) {
+ str = "";
+ } else {
+ str.truncate(str_i);
+ }
+ item = item->parent;
+ i = i->parent();
+ i2 = i;
+ }
+ if(item) {
+ item2 = &*item->it;
+ if(item->it == item->items.begin())
+ i2 = i;
+ ++item->it;
+ item = item2;
+ item->it = item->items.begin();
+ }
+ }
+ if(!function_cats.objects.empty()) {
+ //add "Uncategorized" category if there are functions without category
+ i = new KListViewItem(categoryView, i18n("Uncategorized"));
+ categoryItems[i] = i18n("Uncategorized");
+ if(selected_category == i18n("Uncategorized")) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ }
+ if(!ia_functions.empty()) {
+ //add "Inactive" category if there are inactive functions
+ i = new KListViewItem(categoryView, i18n("Inactive"));
+ categoryItems[i] = i18n("Inactive");
+ if(selected_category == i18n("Inactive")) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ }
+ if(!categoryView->selectedItem()) {
+ //if no category has been selected (previously selected has been renamed/deleted), select "All"
+ selected_category = i18n("All");
+ QListViewItemIterator it(categoryView);
+ if(it.current())
+ categoryView->setSelected(it.current(), true);
+ }
+}
+
+#define UPDATE_SELECTED_FUNCTION QListViewItem *i = functionView->selectedItem(); if(!i) return; selected_function = functionItems[i]; if(!selected_function) return;
+#define CHECK_IF_FUNCTION_STILL_THERE if(!CALCULATOR->stillHasFunction(selected_function)) {KMessageBox::error(this, i18n("Function does not exist anymore.")); emit functionsChanged(); return;}
+
+void QalculateFunctionsDialog::insertFunction() {
+ UPDATE_SELECTED_FUNCTION
+ CHECK_IF_FUNCTION_STILL_THERE
+ emit insertRequest(selected_function);
+}
+
+void QalculateFunctionsDialog::applyFunction() {
+ UPDATE_SELECTED_FUNCTION
+ CHECK_IF_FUNCTION_STILL_THERE
+ emit applyRequest(selected_function);
+}
+
+void QalculateFunctionsDialog::deactivateFunction() {
+ UPDATE_SELECTED_FUNCTION
+ CHECK_IF_FUNCTION_STILL_THERE
+ selected_function->setActive(!selected_function->isActive());
+ emit functionsChanged();
+}
+
+void QalculateFunctionsDialog::deleteFunction() {
+ UPDATE_SELECTED_FUNCTION
+ CHECK_IF_FUNCTION_STILL_THERE
+ if(selected_function->isLocal()) {
+ //ensure that all references are removed in Calculator
+ selected_function->destroy();
+ //update menus and trees
+ emit functionsChanged();
+ }
+}
+
+
+void QalculateFunctionsDialog::editFunction() {
+ UPDATE_SELECTED_FUNCTION
+ CHECK_IF_FUNCTION_STILL_THERE
+ if(!function_edit_dialog) {
+ function_edit_dialog = new QalculateEditFunctionDialog(this);
+ }
+ MathFunction *f = function_edit_dialog->editFunction(QString::null, selected_function);
+ if(f) {
+ selected_function = f;
+ if(!f->isActive()) {
+ selected_category = i18n("Inactive");
+ } else if(f->category().empty()) {
+ selected_category = i18n("Uncategorized");
+ } else {
+ selected_category = "/";
+ selected_category += f->category().c_str();
+ }
+ emit functionsChanged();
+ }
+}
+
+void QalculateFunctionsDialog::newFunction() {
+ if(!function_edit_dialog) {
+ function_edit_dialog = new QalculateEditFunctionDialog(this);
+ }
+ MathFunction *f = NULL;
+ if(selected_category.isEmpty() || selected_category[0] != '/') {
+ f = function_edit_dialog->editFunction();
+ } else {
+ QString str = selected_category;
+ str.remove(0, 1);
+ f = function_edit_dialog->editFunction(str);
+ }
+ if(f) {
+ selected_function = f;
+ if(!f->isActive()) {
+ selected_category = i18n("Inactive");
+ } else if(f->category().empty()) {
+ selected_category = i18n("Uncategorized");
+ } else {
+ selected_category = "/";
+ selected_category += f->category().c_str();
+ }
+ emit functionsChanged();
+ }
+}
+
+void QalculateFunctionsDialog::functionDoubleClicked(QListViewItem*i) {
+ selected_function = functionItems[i];
+ if(!selected_function)
+ return;
+ CHECK_IF_FUNCTION_STILL_THERE
+ if(!function_edit_dialog) {
+ function_edit_dialog = new QalculateEditFunctionDialog(this);
+ }
+ MathFunction *f = function_edit_dialog->editFunction(QString::null, selected_function);
+ if(f) {
+ selected_function = f;
+ if(!f->isActive()) {
+ selected_category = i18n("Inactive");
+ } else if(f->category().empty()) {
+ selected_category = i18n("Uncategorized");
+ } else {
+ selected_category = "/";
+ selected_category += f->category().c_str();
+ }
+ emit functionsChanged();
+ }
+}
+
+
+void QalculateFunctionsDialog::functionSelected() {
+ QListViewItem *selected = functionView->selectedItem();
+ if(selected) {
+ MathFunction *f = functionItems[selected];
+ if(!CALCULATOR->stillHasFunction(f)) {
+ KMessageBox::error(this, i18n("Function does not exist anymore."));
+ selected_function = NULL;
+ emit functionsChanged();
+ return;
+ }
+ //remember selection
+ selected_function = f;
+ editButton->setEnabled(true);
+ insertButton->setEnabled(f->isActive());
+ applyButton->setEnabled(f->isActive() && f->minargs() <= 1);
+ deleteButton->setEnabled(f->isLocal());
+ deactivateButton->setEnabled(true);
+ if(f->isActive()) {
+ deactivateButton->setText(i18n("Deactivate"));
+ } else {
+ deactivateButton->setText(i18n("Activate"));
+ }
+
+ Argument *arg;
+ Argument default_arg;
+ QString str, str2;
+ const ExpressionName *ename = &f->preferredName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) descriptionBrowser);
+ str += "<i><b>";
+ str += ename->name.c_str();
+ str += "</b>";
+ int iargs = f->maxargs();
+ if(iargs < 0) {
+ iargs = f->minargs() + 1;
+ }
+ str += "(";
+ if(iargs != 0) {
+ for(int i2 = 1; i2 <= iargs; i2++) {
+ if(i2 > f->minargs()) {
+ str += "[";
+ }
+ if(i2 > 1) {
+ str += CALCULATOR->getComma().c_str();
+ str += " ";
+ }
+ arg = f->getArgumentDefinition(i2);
+ if(arg && !arg->name().empty()) {
+ str += arg->name().c_str();
+ } else {
+ str += i18n("argument");
+ str += " ";
+ str += QString::number(i2);
+ }
+ if(i2 > f->minargs()) {
+ str += "]";
+ }
+ }
+ if(f->maxargs() < 0) {
+ str += CALCULATOR->getComma().c_str();
+ str += " ...";
+ }
+ }
+ str += ")";
+ for(size_t i2 = 1; i2 <= f->countNames(); i2++) {
+ if(&f->getName(i2) != ename) {
+ str += "<br>";
+ str += f->getName(i2).name.c_str();
+ }
+ }
+ str += "</i>";
+ str += "<br>";
+ if(f->subtype() == SUBTYPE_DATA_SET) {
+ str += "<br>";
+ str2.sprintf(i18n("Retrieves data from the %s data set for a given object and property. If \"info\" is typed as property, a dialog window will pop up with all properties of the object."), f->title().c_str());
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "<br>";
+ }
+ if(!f->description().empty()) {
+ str += "<br>";
+ str2 = f->description().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "<br>";
+ }
+ if(f->subtype() == SUBTYPE_DATA_SET && !((DataSet*) f)->copyright().empty()) {
+ str += "<br>";
+ str2 = ((DataSet*) f)->copyright().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "<br>";
+ }
+ if(iargs) {
+ str += "<br><b>";
+ str += i18n("Arguments");
+ str += "</b><br>";
+ for(int i2 = 1; i2 <= iargs; i2++) {
+ arg = f->getArgumentDefinition(i2);
+ if(arg && !arg->name().empty()) {
+ str += arg->name().c_str();
+ } else {
+ str += QString::number(i2);
+ }
+ str += ": <i>";
+ if(arg) {
+ str2= arg->printlong().c_str();
+ } else {
+ str2= default_arg.printlong().c_str();
+ }
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ if(i2 > f->minargs()) {
+ str += " (";
+ //optional argument
+ str += i18n("optional");
+ if(!f->getDefaultValue(i2).empty()) {
+ str += ", ";
+ //argument default, in description
+ str += i18n("default: ");
+ str += f->getDefaultValue(i2).c_str();
+ }
+ str += ")";
+ }
+ str += "</i><br>";
+ }
+ }
+ if(!f->condition().empty()) {
+ str += "<br>";
+ str += i18n("Requirement");
+ str += ": ";
+ str2 = f->printCondition().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "<br>";
+ }
+ if(f->subtype() == SUBTYPE_DATA_SET) {
+ DataSet *ds = (DataSet*) f;
+ str += "<br><b>";
+ str += i18n("Properties");
+ str += "</b><br>";
+ DataPropertyIter it;
+ DataProperty *dp = ds->getFirstProperty(&it);
+ while(dp) {
+ if(!dp->isHidden()) {
+ if(!dp->title(false).empty()) {
+ str2 = dp->title().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += ": ";
+ }
+ for(size_t i = 1; i <= dp->countNames(); i++) {
+ if(i > 1) str += ", ";
+ str += dp->getName(i).c_str();
+ }
+ if(dp->isKey()) {
+ str += " (";
+ str += i18n("key");
+ str += ")";
+ }
+ str += "<br>";
+ if(!dp->description().empty()) {
+ str += "<i>";
+ str2 = dp->description().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ str += "</i><br>";
+ }
+ }
+ dp = ds->getNextProperty(&it);
+ }
+ }
+ str.replace("\n", "<br>");
+ descriptionBrowser->setText(str);
+ } else {
+ editButton->setEnabled(false);
+ insertButton->setEnabled(false);
+ applyButton->setEnabled(false);
+ deleteButton->setEnabled(false);
+ deactivateButton->setEnabled(false);
+ selected_function = NULL;
+ descriptionBrowser->clear();
+ }
+}
+
+void QalculateFunctionsDialog::addFunctionTreeItem(MathFunction *f) {
+ QListViewItem *i = new KListViewItem(functionView, f->title(true).c_str());
+ functionItems[i] = f;
+ if(f == selected_function) {
+ functionView->setSelected(i, true);
+ }
+}
+
+
+void QalculateFunctionsDialog::categorySelected() {
+ QListViewItem *selected = categoryView->selectedItem();
+ bool no_cat = false, b_all = false, b_inactive = false;
+ functionView->clear();
+ functionItems.clear();
+ if(!selected) {
+ selected_category = "";
+ functionSelected();
+ return;
+ }
+ selected_category = categoryItems[selected];
+ if(selected_category == i18n("All")) {
+ b_all = true;
+ } else if(selected_category == i18n("Uncategorized")) {
+ no_cat = true;
+ } else if(selected_category == i18n("Inactive")) {
+ b_inactive = true;
+ }
+ if(!b_all && !no_cat && !b_inactive && selected_category[0] == '/') {
+ string str = selected_category.ascii();
+ str.erase(str.begin());
+ for(size_t i = 0; i < CALCULATOR->functions.size(); i++) {
+ if(CALCULATOR->functions[i]->isActive() && CALCULATOR->functions[i]->category().substr(0, selected_category.length() - 1) == str) {
+ addFunctionTreeItem(CALCULATOR->functions[i]);
+ }
+ }
+ } else {
+ string str = selected_category.ascii();
+ for(size_t i = 0; i < CALCULATOR->functions.size(); i++) {
+ if((b_inactive && !CALCULATOR->functions[i]->isActive()) || (CALCULATOR->functions[i]->isActive() && (b_all || (no_cat && CALCULATOR->functions[i]->category().empty()) || (!b_inactive && CALCULATOR->functions[i]->category() == str)))) {
+ addFunctionTreeItem(CALCULATOR->functions[i]);
+ }
+ }
+ }
+ if(!selected_function || !functionView->selectedItem()) {
+ QListViewItemIterator it(functionView);
+ if(it.current())
+ functionView->setSelected(it.current(), true);
+ }
+
+}
+
+
+#include "qalculatefunctionsdialog.moc"
diff --git a/src/qalculatefunctionsdialog.h b/src/qalculatefunctionsdialog.h
new file mode 100644
index 0000000..7a0104f
--- /dev/null
+++ b/src/qalculatefunctionsdialog.h
@@ -0,0 +1,89 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEFUNCTIONSDIALOG_H
+#define QALCULATEFUNCTIONSDIALOG_H
+
+#include <kdialog.h>
+#include <qmap.h>
+
+class MathFunction;
+class QalculateEditFunctionDialog;
+class KListView;
+class QListViewItem;
+class QPushButton;
+class KTextBrowser;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateFunctionsDialog : public KDialog {
+
+ Q_OBJECT
+
+public:
+
+ QalculateFunctionsDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateFunctionsDialog();
+
+ QalculateEditFunctionDialog *function_edit_dialog;
+ QString selected_category;
+ MathFunction *selected_function;
+ void addFunctionTreeItem(MathFunction *f);
+ QMap<QListViewItem*, MathFunction*> functionItems;
+ QMap<QListViewItem*, QString> categoryItems;
+
+ KListView *categoryView;
+ KListView *functionView;
+ QPushButton *newButton;
+ QPushButton *editButton;
+ QPushButton *deleteButton;
+ QPushButton *deactivateButton;
+ QPushButton *insertButton;
+ QPushButton *applyButton;
+ QPushButton *helpButton;
+ QPushButton *buttonClose;
+ KTextBrowser *descriptionBrowser;
+
+public slots:
+
+ void updateFunctionTree();
+ void functionDoubleClicked(QListViewItem*);
+ void functionSelected();
+ void categorySelected();
+ void insertFunction();
+ void applyFunction();
+ void deactivateFunction();
+ void deleteFunction();
+ void editFunction();
+ void newFunction();
+
+protected slots:
+
+ void slotHelp();
+
+signals:
+
+ void functionsChanged();
+ void insertRequest(MathFunction*);
+ void applyRequest(MathFunction*);
+
+};
+
+#endif
diff --git a/src/qalculateimportcsvdialog.cpp b/src/qalculateimportcsvdialog.cpp
new file mode 100644
index 0000000..88f8044
--- /dev/null
+++ b/src/qalculateimportcsvdialog.cpp
@@ -0,0 +1,216 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateimportcsvdialog.h"
+#include "qalculate_kde_utils.h"
+
+#include <qlayout.h>
+#include <kurlrequester.h>
+#include <klineedit.h>
+#include <qlabel.h>
+#include <qradiobutton.h>
+#include <qcheckbox.h>
+#include <qpushbutton.h>
+#include <kcombobox.h>
+#include <qspinbox.h>
+#include <qbuttongroup.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <kapplication.h>
+
+extern tree_struct variable_cats;
+
+QalculateImportCSVDialog::QalculateImportCSVDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Import CSV File"), Ok | Cancel | Help, Ok, true) {
+
+ setMainWidget(new QWidget(this));
+ QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
+ grid->addWidget(new QLabel(i18n("File:"), mainWidget()), 0, 0);
+ fileEdit = new KURLRequester(mainWidget());
+ fileEdit->setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly);
+ fileEdit->setCaption(i18n("Import CSV File"));
+ grid->addWidget(fileEdit, 0, 1);
+ grid->addWidget(new QLabel(i18n("Import as:"), mainWidget()), 1, 0);
+ QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addLayout(hbox, 1, 1);
+ QButtonGroup *group = new QButtonGroup();
+ matrixButton = new QRadioButton(i18n("Matrix"), mainWidget());
+ group->insert(matrixButton, 0);
+ hbox->addWidget(matrixButton);
+ matrixButton->setChecked(true);
+ vectorsButton = new QRadioButton(i18n("Vectors"), mainWidget());
+ group->insert(vectorsButton, 1);
+ hbox->addWidget(vectorsButton);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 2, 0);
+ nameEdit = new KLineEdit(mainWidget());
+ grid->addWidget(nameEdit, 2, 1);
+ grid->addWidget(new QLabel(i18n("Descriptive name:"), mainWidget()), 3, 0);
+ titleEdit = new KLineEdit(mainWidget());
+ grid->addWidget(titleEdit, 3, 1);
+ grid->addWidget(new QLabel(i18n("Category:"), mainWidget()), 4, 0);
+ categoryCombo = new KComboBox(mainWidget());
+ categoryCombo->setMaximumWidth(250);
+ categoryCombo->setEditable(true);
+ grid->addWidget(categoryCombo, 4, 1);
+ grid->addWidget(new QLabel(i18n("First row:"), mainWidget()), 5, 0);
+ firstRowBox = new QSpinBox(1, 1000, 1, mainWidget());
+ grid->addWidget(firstRowBox, 5, 1);
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 6, 6, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ includesHeadingsButton = new QCheckBox(i18n("Includes headings"), mainWidget());
+ includesHeadingsButton->setChecked(true);
+ hbox->addWidget(includesHeadingsButton);
+ grid->addWidget(new QLabel(i18n("Delimiter:"), mainWidget()), 7, 0);
+ delimiterCombo = new KComboBox(mainWidget());
+ delimiterCombo->setMaximumWidth(250);
+ delimiterCombo->insertItem(i18n("Comma"));
+ delimiterCombo->insertItem(i18n("Tabulator"));
+ delimiterCombo->insertItem(i18n("Semicolon"));
+ delimiterCombo->insertItem(i18n("Space"));
+ delimiterCombo->insertItem(i18n("Other"));
+ delimiterCombo->setEditable(false);
+ grid->addWidget(delimiterCombo, 7, 1);
+ otherDelimiterEdit = new KLineEdit(mainWidget());
+ grid->addWidget(otherDelimiterEdit, 8, 1);
+ otherDelimiterEdit->setEnabled(false);
+
+ connect(delimiterCombo, SIGNAL(activated(int)), this, SLOT(delimiterChanged(int)));
+ connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
+
+}
+
+QalculateImportCSVDialog::~QalculateImportCSVDialog() {
+}
+
+void QalculateImportCSVDialog::slotHelp() {
+ KApplication::kApplication()->invokeHelp("qalculate-import-export-csv");
+}
+
+void QalculateImportCSVDialog::delimiterChanged(int i) {
+ otherDelimiterEdit->setEnabled(i == 4);
+}
+
+void QalculateImportCSVDialog::slotOk() {
+
+ QString str = fileEdit->url().stripWhiteSpace();
+ if(str.isEmpty()) {
+ //no name -- open dialog again
+ fileEdit->setFocus();
+ KMessageBox::error(this, i18n("No file name entered."));
+ return;
+ }
+ string delimiter = "";
+ switch(delimiterCombo->currentItem()) {
+ case 0: {
+ delimiter = ",";
+ break;
+ }
+ case 1: {
+ delimiter = "\t";
+ break;
+ }
+ case 2: {
+ delimiter = ";";
+ break;
+ }
+ case 3: {
+ delimiter = " ";
+ break;
+ }
+ case 4: {
+ delimiter = otherDelimiterEdit->text().ascii();
+ break;
+ }
+ }
+ if(delimiter.empty()) {
+ //no delimiter -- open dialog again
+ otherDelimiterEdit->setFocus();
+ KMessageBox::error(this, i18n("No delimiter selected."));
+ return;
+ }
+ if(!CALCULATOR->importCSV(str.ascii(), firstRowBox->value(), includesHeadingsButton->isChecked(), delimiter, matrixButton->isChecked(), nameEdit->text().ascii(), titleEdit->text().ascii(), categoryCombo->lineEdit()->text().ascii())) {
+ KMessageBox::error(this, i18n("An error occured when importing the CSV file."));
+ reject();
+ }
+ accept();
+
+}
+
+bool QalculateImportCSVDialog::importCSVFile() {
+
+ fileEdit->setFocus();
+
+ nameEdit->clear();
+ fileEdit->clear();
+ titleEdit->clear();
+
+ //QStringList cats;
+ QString catstr;
+ categoryCombo->clear();
+ tree_struct *item, *item2;
+ variable_cats.it = variable_cats.items.begin();
+ if(variable_cats.it != variable_cats.items.end()) {
+ item = &*variable_cats.it;
+ ++variable_cats.it;
+ item->it = item->items.begin();
+ } else {
+ item = NULL;
+ }
+
+ catstr = "";
+ while(item) {
+ if(!catstr.isEmpty()) catstr += "/";
+ catstr += item->item.c_str();
+ categoryCombo->insertItem(catstr);
+ while(item && item->it == item->items.end()) {
+ int str_i = catstr.findRev("/");
+ if(str_i < 0) {
+ catstr = "";
+ } else {
+ catstr.truncate(str_i);
+ }
+ item = item->parent;
+ }
+ if(item) {
+ item2 = &*item->it;
+ ++item->it;
+ item = item2;
+ item->it = item->items.begin();
+ }
+ }
+
+ categoryCombo->lineEdit()->clear();
+
+ if(exec() == QDialog::Accepted) {
+ return true;
+ }
+ return false;
+}
+
+void QalculateImportCSVDialog::nameChanged(const QString &name) {
+ if(name.isNull()) return;
+ if(!CALCULATOR->variableNameIsValid(name.ascii())) {
+ nameEdit->blockSignals(true);
+ nameEdit->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str());
+ nameEdit->blockSignals(false);
+ }
+}
+
+#include "qalculateimportcsvdialog.moc"
diff --git a/src/qalculateimportcsvdialog.h b/src/qalculateimportcsvdialog.h
new file mode 100644
index 0000000..8b6e96e
--- /dev/null
+++ b/src/qalculateimportcsvdialog.h
@@ -0,0 +1,65 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEIMPORTCSVDIALOG_H
+#define QALCULATEIMPORTCSVDIALOG_H
+
+#include <kdialogbase.h>
+
+class KLineEdit;
+class KComboBox;
+class QSpinBox;
+class QCheckBox;
+class QRadioButton;
+class KURLRequester;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateImportCSVDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateImportCSVDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateImportCSVDialog();
+
+ KLineEdit *nameEdit, *titleEdit, *otherDelimiterEdit;
+ KComboBox *categoryCombo, *delimiterCombo;
+ QSpinBox *firstRowBox;
+ QCheckBox *includesHeadingsButton;
+ QRadioButton *matrixButton, *vectorsButton;
+ KURLRequester *fileEdit;
+
+ bool importCSVFile();
+
+public slots:
+
+ void delimiterChanged(int);
+ void nameChanged(const QString&);
+
+protected slots:
+
+ void slotHelp();
+ void slotOk();
+
+};
+
+#endif
diff --git a/src/qalculateinsertfunctiondialog.cpp b/src/qalculateinsertfunctiondialog.cpp
new file mode 100644
index 0000000..c0fc808
--- /dev/null
+++ b/src/qalculateinsertfunctiondialog.cpp
@@ -0,0 +1,404 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateinsertfunctiondialog.h"
+#include "qalculate_kde_utils.h"
+#include <qvbox.h>
+#include <kactivelabel.h>
+#include <klineedit.h>
+#include <qlabel.h>
+#include <qgrid.h>
+#include <qhbox.h>
+#include <klocale.h>
+#include <qspinbox.h>
+#include <kcombobox.h>
+#include <qhbuttongroup.h>
+#include <qradiobutton.h>
+#include <qstring.h>
+#include <qpushbutton.h>
+#include <kdatepicker.h>
+#include <kfiledialog.h>
+#include <kdeversion.h>
+#include <kstdguiitem.h>
+#include "buttonwithindexsignal.h"
+#include "qalculateinsertmatrixvectordialog.h"
+
+extern QWidget *expressionWidget;
+extern PrintOptions printops;
+extern EvaluationOptions evalops;
+
+QalculateInsertFunctionDialog::QalculateInsertFunctionDialog(MathFunction *f, QWidget *parent, const QString &selected_text, const char *name) : KDialogBase(parent, name, true, f->title(true).c_str(), Ok|Apply|Cancel, Ok) {
+
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ setButtonOKText(i18n("Insert"));
+ setButtonApplyText(i18n("Execute"));
+#else
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 3
+ setButtonOK(KGuiItem(i18n("Insert")));
+#else
+ setButtonOK(KStdGuiItem::insert());
+#endif
+ setButtonApply(KGuiItem(i18n("Execute")));
+#endif
+ mathFunction = f;
+ QVBox *box = makeVBoxMainWidget();
+ box->setSpacing(12);
+ QString titlestr = "<font size=\"5\">";
+ titlestr += mathFunction->title(true).c_str();
+ titlestr += "</font>";
+ new QLabel(titlestr, box);
+ int args = 0;
+ bool has_vector = false;
+ if(mathFunction->args() > 0) {
+ args = mathFunction->args();
+ } else if(mathFunction->minargs() > 0) {
+ args = mathFunction->minargs() + 1;
+ has_vector = true;
+ } else {
+ args = 1;
+ has_vector = true;
+ }
+ QGrid *table = new QGrid(3, box);
+ table->setSpacing(6);
+ table->setMargin(12);
+ table->setFrameStyle(QFrame::Sunken | QFrame::GroupBoxPanel);
+ label.resize(args);
+ entry.resize(args);
+ type_label.resize(args);
+ QString argstr, typestr, defstr, argtype;
+ //create argument entries
+ Argument *arg;
+ for(int i = 0; i < args; i++) {
+ arg = mathFunction->getArgumentDefinition(i + 1);
+ if(!arg || arg->name().empty()) {
+ if(args == 1) {
+ argstr = i18n("Value:");
+ } else {
+ argstr = i18n("Argument");
+ argstr += " ";
+ argstr += QString::number(i + 1);
+ argstr += ":";
+ }
+ } else {
+ argstr = arg->name().c_str();
+ argstr += ":";
+ }
+ typestr = "";
+ argtype = "";
+ defstr = mathFunction->getDefaultValue(i + 1).c_str();
+ if(arg && (arg->suggestsQuotes() || arg->type() == ARGUMENT_TYPE_TEXT) && defstr.length() >= 2 && defstr[0] == '\"' && defstr[defstr.length() - 1] == '\"') {
+ defstr.remove(0, 1);
+ defstr.truncate(defstr.length() - 1);
+ }
+ label[i] = new QLabel(argstr, table);
+ if(arg) {
+ switch(arg->type()) {
+ case ARGUMENT_TYPE_INTEGER: {
+ IntegerArgument *iarg = (IntegerArgument*) arg;
+ int min = -1000000, max = 1000000;
+ if(iarg->min()) {
+ min = iarg->min()->intValue();
+ }
+ if(iarg->max()) {
+ max = iarg->max()->intValue();
+ }
+ QSpinBox *qsp = new QSpinBox(min, max, 1, table);
+ entry[i] = qsp;
+ qsp->setButtonSymbols(QSpinBox::PlusMinus);
+ int selected_value = 0;
+ bool convok = false;
+ if(i == 0 && !selected_text.isEmpty()) {
+ selected_value = selected_text.toInt(&convok);
+ }
+ if(convok && selected_value >= min && selected_value <= max) {
+ qsp->setValue(selected_value);
+ } else if(!mathFunction->getDefaultValue(i + 1).empty()) {
+ qsp->setValue(QString(mathFunction->getDefaultValue(i + 1).c_str()).toInt());
+ } else if(!arg->zeroForbidden() && min <= 0 && max >= 0) {
+ qsp->setValue(0);
+ } else {
+ if(max < 0) {
+ qsp->setValue(max);
+ } else if(min <= 1) {
+ qsp->setValue(1);
+ } else {
+ qsp->setValue(min);
+ }
+ }
+ break;
+ }
+ case ARGUMENT_TYPE_BOOLEAN: {
+ QHButtonGroup *bg = new QHButtonGroup(table);
+ entry[i] = bg;
+ bg->setFrameStyle(QFrame::Plain | QFrame::NoFrame);
+ bg->setMargin(0);
+ bg->setRadioButtonExclusive(TRUE);
+ bg->insert(new QRadioButton(i18n("True"), bg), 1);
+ bg->insert(new QRadioButton(i18n("False"), bg), 0);
+ QString str = selected_text.stripWhiteSpace();
+ if(i == 0 && str == "1") {
+ bg->setButton(1);
+ } else if(i == 0 && str == "0") {
+ bg->setButton(0);
+ } else if(defstr == "1") {
+ bg->setButton(1);
+ } else {
+ bg->setButton(0);
+ }
+ break;
+ }
+ case ARGUMENT_TYPE_DATA_PROPERTY: {
+ if(mathFunction->subtype() == SUBTYPE_DATA_SET) {
+ KComboBox *cb = new KComboBox(table);
+ entry[i] = cb;
+ DataPropertyIter it;
+ DataSet *ds = (DataSet*) mathFunction;
+ DataProperty *dp = ds->getFirstProperty(&it);
+ bool active_set = false;
+ while(dp) {
+ if(!dp->isHidden()) {
+ cb->insertItem(dp->title().c_str());
+ if(!active_set && defstr == dp->getName().c_str()) {
+ cb->setCurrentItem(cb->count() - 1);
+ active_set = true;
+ }
+ }
+ dp = ds->getNextProperty(&it);
+ }
+ cb->insertItem(i18n("Info"));
+ if(!active_set) {
+ cb->setCurrentItem(cb->count() - 1);
+ }
+ break;
+ }
+ }
+ default: {
+ if(i >= mathFunction->minargs() && !has_vector) {
+ typestr = "(";
+ typestr += i18n("optional");
+ }
+ argtype = arg->print().c_str();
+ if(typestr.isEmpty()) {
+ typestr = "(";
+ } else if(!argtype.isEmpty()) {
+ typestr += " ";
+ }
+ if(!argtype.isEmpty()) {
+ typestr += argtype;
+ }
+ typestr += ")";
+ if(typestr.length() == 2) {
+ typestr = "";
+ }
+ entry[i] = new KLineEdit(table);
+ if(i == 0 && !selected_text.isEmpty()) {
+ ((KLineEdit*) entry[i])->setText(selected_text);
+ } else {
+ ((KLineEdit*) entry[i])->setText(defstr);
+ }
+ }
+ }
+ } else {
+ entry[i] = new KLineEdit(table);
+ if(i == 0 && !selected_text.isEmpty()) {
+ ((KLineEdit*) entry[i])->setText(selected_text);
+ } else {
+ ((KLineEdit*) entry[i])->setText(defstr);
+ }
+ }
+ if(typestr.isEmpty() && i >= mathFunction->minargs() && !has_vector) {
+ typestr = "(";
+ typestr += i18n("optional");
+ typestr += ")";
+ }
+ if(arg) {
+ switch(arg->type()) {
+ case ARGUMENT_TYPE_DATE: {
+ typestr.remove(0, 1);
+ typestr.remove(typestr.length() - 1, 1);
+ type_label[i] = new ButtonWithIndexSignal(typestr, i, table);
+ QObject::connect(type_label[i], SIGNAL(clickedWithIndex(int)), this, SLOT(selectDate(int)));
+ break;
+ }
+ case ARGUMENT_TYPE_MATRIX: {
+ typestr.remove(0, 1);
+ typestr.remove(typestr.length() - 1, 1);
+ type_label[i] = new ButtonWithIndexSignal(typestr, i, table);
+ QObject::connect(type_label[i], SIGNAL(clickedWithIndex(int)), this, SLOT(insertMatrix(int)));
+ break;
+ }
+ case ARGUMENT_TYPE_VECTOR: {
+ typestr.remove(0, 1);
+ typestr.remove(typestr.length() - 1, 1);
+ type_label[i] = new ButtonWithIndexSignal(typestr, i, table);
+ QObject::connect(type_label[i], SIGNAL(clickedWithIndex(int)), this, SLOT(insertVector(int)));
+ break;
+ }
+ case ARGUMENT_TYPE_FILE: {
+ typestr.remove(0, 1);
+ typestr.remove(typestr.length() - 1, 1);
+ type_label[i] = new ButtonWithIndexSignal(typestr, i, table);
+ QObject::connect(type_label[i], SIGNAL(clickedWithIndex(int)), this, SLOT(selectFile(int)));
+ break;
+ }
+ default: {
+ type_label[i] = new QLabel(typestr, table);
+ }
+ }
+ } else {
+ type_label[i] = new QLabel(typestr, table);
+ }
+ if(i == 0) entry[0]->setFocus();
+ }
+ //display function description
+ if(!mathFunction->description().empty()) {
+ QString str = mathFunction->description().c_str();
+ str.replace("<", "&lt;");
+ str.replace(">", "&gt;");
+ str.replace("\n", "<br>");
+ KActiveLabel *descrLabel = new KActiveLabel(str, box);
+ descrLabel->setAlignment(Qt::AlignJustify);
+ enableButtonSeparator(true);
+ }
+}
+
+QalculateInsertFunctionDialog::~QalculateInsertFunctionDialog() {
+}
+
+QString QalculateInsertFunctionDialog::functionExpression() {
+ QString str = mathFunction->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionWidget).name.c_str(), str2;
+ str += "(";
+ int args = 0;
+ if(mathFunction->args() > 0) {
+ args = mathFunction->args();
+ } else if(mathFunction->minargs() > 0) {
+ args = mathFunction->minargs() + 1;
+ } else {
+ args = 1;
+ }
+ for(int i = 0; i < args; i++) {
+ if(mathFunction->getArgumentDefinition(i + 1) && mathFunction->getArgumentDefinition(i + 1)->type() == ARGUMENT_TYPE_BOOLEAN) {
+ if(((QButtonGroup*) entry[i])->id(((QButtonGroup*) entry[i])->selected()) == 1) {
+ str2 = "1";
+ } else {
+ str2 = "0";
+ }
+ } else if(mathFunction->getArgumentDefinition(i + 1) && mathFunction->getArgumentDefinition(i + 1)->type() == ARGUMENT_TYPE_INTEGER) {
+ str2 = ((QSpinBox*) entry[i])->text();
+ } else if(mathFunction->subtype() == SUBTYPE_DATA_SET && mathFunction->getArgumentDefinition(i + 1) && mathFunction->getArgumentDefinition(i + 1)->type() == ARGUMENT_TYPE_DATA_PROPERTY) {
+ int index = ((KComboBox*) entry[i])->currentItem();
+ DataPropertyIter it;
+ DataSet *ds = (DataSet*) mathFunction;
+ DataProperty *dp = ds->getFirstProperty(&it);
+ while(dp) {
+ if(!dp->isHidden()) {
+ if(index <= 0) break;
+ index--;
+ }
+ dp = ds->getNextProperty(&it);
+ }
+ if(dp) {
+ str2 = dp->getName().c_str();
+ } else {
+ str2 = "info";
+ }
+ } else {
+ str2 = ((KLineEdit*) entry[i])->text();
+ }
+ //if the minimum number of function arguments have been filled, do not add anymore if entry is empty
+ if(i >= mathFunction->minargs()) {
+ str2 = str2.stripWhiteSpace();
+ }
+ if((i < mathFunction->minargs() || !str2.isEmpty()) && mathFunction->getArgumentDefinition(i + 1) && (mathFunction->getArgumentDefinition(i + 1)->suggestsQuotes() || (mathFunction->getArgumentDefinition(i + 1)->type() == ARGUMENT_TYPE_TEXT && str2.find(CALCULATOR->getComma().c_str()) >= 0))) {
+ if(str2.length() < 1 || (str2[0] != '\"' && str[0] != '\'')) {
+ str2.insert(0, "\"");
+ str2 += "\"";
+ }
+ }
+ if(i > 0) {
+ str += CALCULATOR->getComma().c_str();
+ str += " ";
+ }
+ str += str2;
+ }
+ str += ")";
+ return str;
+}
+
+void QalculateInsertFunctionDialog::slotOk() {
+ accept();
+}
+
+void QalculateInsertFunctionDialog::slotApply() {
+ done(100);
+}
+
+void QalculateInsertFunctionDialog::selectDate(int index) {
+ KDialogBase *dialog = new KDialogBase(this, 0, true, i18n("Date"), Ok|Cancel);
+ KDatePicker *datePicker;
+ QDate date(QDate::fromString(((KLineEdit*) entry[index])->text(), Qt::ISODate));
+ if(date.isValid()) datePicker = new KDatePicker(dialog->makeVBoxMainWidget(), date);
+ else datePicker = new KDatePicker(dialog->makeVBoxMainWidget());
+ if(dialog->exec() == QDialog::Accepted) {
+ ((KLineEdit*) entry[index])->setText(datePicker->date().toString(Qt::ISODate));
+ }
+ dialog->deleteLater();
+}
+void QalculateInsertFunctionDialog::selectFile(int index) {
+ QString filename = KFileDialog::getSaveFileName(((KLineEdit*) entry[index])->text(), QString::null, this, i18n("File"));
+ if(!filename.isEmpty()) {
+ ((KLineEdit*) entry[index])->setText(filename);
+ }
+}
+void QalculateInsertFunctionDialog::insertMatrix(int index) {
+ QalculateInsertMatrixVectorDialog *d = new QalculateInsertMatrixVectorDialog(this);
+ QString str = ((KLineEdit*) entry[index])->text();
+ MathStructure mstruct;
+ if(!str.isEmpty()) {
+ CALCULATOR->parse(&mstruct, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options));
+ }
+ if(mstruct.isVector()) {
+ str = d->editMatrixVector(&mstruct, false);
+ } else {
+ str = d->editMatrixVector(NULL, false);
+ }
+ if(!str.isEmpty()) {
+ ((KLineEdit*) entry[index])->setText(str);
+ }
+ d->deleteLater();
+}
+void QalculateInsertFunctionDialog::insertVector(int index) {
+ QalculateInsertMatrixVectorDialog *d = new QalculateInsertMatrixVectorDialog(this);
+ QString str = ((KLineEdit*) entry[index])->text();
+ MathStructure mstruct;
+ if(!str.isEmpty()) {
+ CALCULATOR->parse(&mstruct, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options));
+ }
+ if(mstruct.isVector()) {
+ str = d->editMatrixVector(&mstruct, true);
+ } else {
+ str = d->editMatrixVector(NULL, true);
+ }
+ if(!str.isEmpty()) {
+ ((KLineEdit*) entry[index])->setText(str);
+ }
+ d->deleteLater();
+}
+
+#include "qalculateinsertfunctiondialog.moc"
diff --git a/src/qalculateinsertfunctiondialog.h b/src/qalculateinsertfunctiondialog.h
new file mode 100644
index 0000000..5954196
--- /dev/null
+++ b/src/qalculateinsertfunctiondialog.h
@@ -0,0 +1,56 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEINSERTFUNCTIONDIALOG_H
+#define QALCULATEINSERTFUNCTIONDIALOG_H
+
+#include <kdialogbase.h>
+#include <qvaluevector.h>
+
+class MathFunction;
+
+class QalculateInsertFunctionDialog : public KDialogBase {
+ Q_OBJECT
+
+public:
+
+ QalculateInsertFunctionDialog(MathFunction *f, QWidget *parent = 0, const QString &selected_text = QString::null, const char *name = 0);
+ virtual ~QalculateInsertFunctionDialog();
+
+ QString functionExpression();
+
+ MathFunction *mathFunction;
+
+ QValueVector<QWidget*> label;
+ QValueVector<QWidget*> entry;
+ QValueVector<QWidget*> type_label;
+
+protected slots:
+
+ void slotOk();
+ void slotApply();
+
+ void selectDate(int);
+ void selectFile(int);
+ void insertMatrix(int);
+ void insertVector(int);
+
+};
+
+#endif
diff --git a/src/qalculateinsertmatrixvectordialog.cpp b/src/qalculateinsertmatrixvectordialog.cpp
new file mode 100644
index 0000000..6e6f994
--- /dev/null
+++ b/src/qalculateinsertmatrixvectordialog.cpp
@@ -0,0 +1,381 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateinsertmatrixvectordialog.h"
+#include "qalculate_kde_utils.h"
+
+#include <qtable.h>
+#include <qgrid.h>
+#include <klineedit.h>
+#include <qpushbutton.h>
+#include <kcombobox.h>
+#include <qlabel.h>
+#include <klocale.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <qcheckbox.h>
+#include <kmessagebox.h>
+#include <qspinbox.h>
+#include <qlayout.h>
+#include <qbuttongroup.h>
+#include <qradiobutton.h>
+#include <kapplication.h>
+#include <kdeversion.h>
+#include <kstdguiitem.h>
+
+extern PrintOptions printops;
+
+class QalculateInsertMatrixTableItem : public QTableItem {
+
+public:
+
+ QalculateInsertMatrixTableItem(QTable *table);
+ QalculateInsertMatrixTableItem(QTable *table, const QString & text);
+
+ int alignment() const;
+
+};
+
+class QalculateInsertMatrixTable : public QTable {
+
+ public:
+
+ QalculateInsertMatrixTable(QWidget *parent = 0, const char *name = 0) : QTable(parent, name) {}
+ QalculateInsertMatrixTable(int numRows, int numCols, QWidget *parent = 0, const char *name = 0) : QTable(numRows, numCols, parent, name) {}
+
+ QWidget *beginEdit(int row, int col, bool replace) {
+ QWidget *w = QTable::beginEdit(row, col, replace);
+ ((QLineEdit*) w)->selectAll();
+ return w;
+ }
+
+};
+
+
+QalculateInsertMatrixVectorDialog::QalculateInsertMatrixVectorDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Variable"), Ok | Cancel | User1, Ok, true, KGuiItem(i18n("Insert Selection"))) {
+
+ setMainWidget(new QWidget(this));
+ QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
+ grid->addWidget(new QLabel(i18n("Rows:"), mainWidget()), 0, 0);
+ rowsBox = new QSpinBox(1, 1000, 1, mainWidget());
+ grid->addWidget(rowsBox, 0, 1);
+ grid->addWidget(new QLabel(i18n("Columns:"), mainWidget()), 1, 0);
+ columnsBox = new QSpinBox(1, 1000, 1, mainWidget());
+ grid->addWidget(columnsBox, 1, 1);
+ QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 2, 2, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ QButtonGroup *group = new QButtonGroup();
+ matrixButton = new QRadioButton(i18n("Matrix"), mainWidget());
+ group->insert(matrixButton, 0);
+ hbox->addWidget(matrixButton);
+ vectorButton = new QRadioButton(i18n("Vector"), mainWidget());
+ group->insert(vectorButton, 1);
+ hbox->addWidget(vectorButton);
+ elementsLabel = new QLabel(i18n("Elements:"), mainWidget());
+ grid->addMultiCellWidget(elementsLabel, 3, 3, 0, 1);
+ elementsTable = new QalculateInsertMatrixTable(0, 0, mainWidget());
+ grid->addMultiCellWidget(elementsTable, 4, 4, 0, 1);
+ elementsTable->setSelectionMode(QTable::Single);
+
+ insertSelectionButton = actionButton(User1);
+ onSelectionChanged();
+
+ connect(insertSelectionButton, SIGNAL(clicked()), this, SLOT(insertSelection()));
+ connect(elementsTable, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
+ connect(rowsBox, SIGNAL(valueChanged(int)), this, SLOT(rowsChanged(int)));
+ connect(columnsBox, SIGNAL(valueChanged(int)), this, SLOT(columnsChanged(int)));
+ connect(group, SIGNAL(clicked(int)), this, SLOT(typeChanged(int)));
+
+}
+
+QalculateInsertMatrixVectorDialog::~QalculateInsertMatrixVectorDialog() {}
+
+void QalculateInsertMatrixVectorDialog::onSelectionChanged() {
+ insertSelectionButton->setEnabled(elementsTable->currentSelection() >= 0);
+}
+void QalculateInsertMatrixVectorDialog::typeChanged(int i) {
+ if(i == 0) {
+ elementsLabel->setText(i18n("Elements:"));
+ bool b = true;
+ for(int index_r = elementsTable->numRows() - 1; index_r >= 0 && b; index_r--) {
+ for(int index_c = elementsTable->numCols() - 1; index_c >= 0; index_c--) {
+ if(elementsTable->text(index_r, index_c).isEmpty()) {
+ elementsTable->setText(index_r, index_c, "0");
+ } else {
+ b = false;
+ break;
+ }
+ }
+ }
+ } else {
+ elementsLabel->setText(i18n("Elements (in horizontal order):"));
+ }
+}
+void QalculateInsertMatrixVectorDialog::rowsChanged(int i) {
+ int r = elementsTable->numRows();
+ elementsTable->setNumRows(i);
+ bool b = matrixButton->isChecked();
+ for(int index_r = r; index_r < i; index_r++) {
+ for(int index_c = 0; index_c < elementsTable->numCols(); index_c++) {
+ if(b) elementsTable->setItem(index_r, index_c, new QalculateInsertMatrixTableItem(elementsTable, "0"));
+ else elementsTable->setItem(index_r, index_c, new QalculateInsertMatrixTableItem(elementsTable));
+ }
+ }
+}
+void QalculateInsertMatrixVectorDialog::columnsChanged(int i) {
+ int c = elementsTable->numCols();
+ elementsTable->setNumCols(i);
+ bool b = matrixButton->isChecked();
+ for(int index_r = 0; index_r < elementsTable->numRows(); index_r++) {
+ for(int index_c = c; index_c < i; index_c++) {
+ if(b) elementsTable->setItem(index_r, index_c, new QalculateInsertMatrixTableItem(elementsTable, "0"));
+ else elementsTable->setItem(index_r, index_c, new QalculateInsertMatrixTableItem(elementsTable));
+ }
+ }
+}
+
+QString QalculateInsertMatrixVectorDialog::newVector() {
+ return editMatrixVector(NULL, true);
+}
+QString QalculateInsertMatrixVectorDialog::newMatrix() {
+ return editMatrixVector(NULL, false);
+}
+
+void QalculateInsertMatrixVectorDialog::slotOk() {
+ int r = rowsBox->value();
+ int c = columnsBox->value();
+ if(vectorButton->isChecked()) {
+ bool b = false;
+ matrixstr = "[";
+ for(int index_r = 0; index_r < r; index_r++) {
+ for(int index_c = 0; index_c < c; index_c++) {
+ if(!elementsTable->text(index_r, index_c).isEmpty()) {
+ QString str2 = elementsTable->text(index_r, index_c).stripWhiteSpace();
+ if(!str2.isEmpty()) {
+ if(b) {
+ matrixstr += CALCULATOR->getComma();
+ matrixstr += " ";
+ } else {
+ b = true;
+ }
+ matrixstr += str2;
+ }
+ }
+ }
+ }
+ matrixstr += "]";
+ } else {
+ matrixstr = "[";
+ bool b1 = false;
+ for(int index_r = 0; index_r < r; index_r++) {
+ if(b1) {
+ matrixstr += CALCULATOR->getComma();
+ matrixstr += " ";
+ } else {
+ b1 = true;
+ }
+ matrixstr += "[";
+ bool b2 = false;
+ for(int index_c = 0; index_c < c; index_c++) {
+ if(b2) {
+ matrixstr += CALCULATOR->getComma();
+ matrixstr += " ";
+ } else {
+ b2 = true;
+ }
+ matrixstr += elementsTable->text(index_r, index_c).stripWhiteSpace();
+ }
+ matrixstr += "]";
+ }
+ matrixstr += "]";
+ }
+ accept();
+}
+void QalculateInsertMatrixVectorDialog::insertSelection() {
+ QTableSelection sel = elementsTable->selection(elementsTable->currentSelection());
+ if(vectorButton->isChecked()) {
+ bool b = false;
+ matrixstr = "[";
+ for(int index_r = sel.topRow(); index_r <= sel.bottomRow(); index_r++) {
+ for(int index_c = sel.leftCol(); index_c <= sel.rightCol(); index_c++) {
+ if(!elementsTable->text(index_r, index_c).isEmpty()) {
+ QString str2 = elementsTable->text(index_r, index_c).stripWhiteSpace();
+ if(!str2.isEmpty()) {
+ if(b) {
+ matrixstr += CALCULATOR->getComma();
+ matrixstr += " ";
+ } else {
+ b = true;
+ }
+ matrixstr += str2;
+ }
+ }
+ }
+ }
+ matrixstr += "]";
+ } else {
+ matrixstr = "[";
+ bool b1 = false;
+ for(int index_r = sel.topRow(); index_r <= sel.bottomRow(); index_r++) {
+ if(b1) {
+ matrixstr += CALCULATOR->getComma();
+ matrixstr += " ";
+ } else {
+ b1 = true;
+ }
+ matrixstr += "[";
+ bool b2 = false;
+ for(int index_c = sel.leftCol(); index_c <= sel.rightCol(); index_c++) {
+ if(b2) {
+ matrixstr += CALCULATOR->getComma();
+ matrixstr += " ";
+ } else {
+ b2 = true;
+ }
+ matrixstr += elementsTable->text(index_r, index_c).stripWhiteSpace();
+ }
+ matrixstr += "]";
+ }
+ matrixstr += "]";
+ }
+ accept();
+}
+
+QString QalculateInsertMatrixVectorDialog::editMatrixVector(const MathStructure *initial_value, bool create_vector, bool is_text_struct, bool is_result) {
+
+ if(initial_value && !initial_value->isVector()) {
+ return NULL;
+ }
+
+ if(initial_value) {
+ create_vector = !initial_value->isMatrix();
+ }
+ if(create_vector) {
+ vectorButton->setChecked(true);
+ elementsLabel->setText(i18n("Elements (in horizontal order):"));
+ } else {
+ matrixButton->setChecked(true);
+ elementsLabel->setText(i18n("Elements:"));
+ }
+
+ if(is_result) {
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ setButtonOKText(i18n("Insert"));
+ setButtonCancelText(KStdGuiItem::close().text());
+#else
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 3
+ setButtonOK(KGuiItem(i18n("Insert")));
+#else
+ setButtonOK(KStdGuiItem::insert());
+#endif
+ setButtonCancel(KStdGuiItem::close());
+#endif
+ actionButton(Cancel)->setDefault(true);
+ actionButton(Cancel)->setFocus();
+ if(create_vector) {
+ setCaption(i18n("Vector Result"));
+ } else {
+ setCaption(i18n("Matrix Result"));
+ }
+ } else {
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ setButtonOKText(KStdGuiItem::ok().text());
+ setButtonCancelText(KStdGuiItem::cancel().text());
+#else
+ setButtonOK(KStdGuiItem::ok());
+ setButtonCancel(KStdGuiItem::cancel());
+#endif
+ actionButton(Ok)->setDefault(true);
+ elementsTable->setFocus();
+ if(create_vector) {
+ setCaption(i18n("Vector"));
+ } else {
+ setCaption(i18n("Matrix"));
+ }
+ }
+
+ int r = 4, c = 4;
+ if(create_vector) {
+ if(initial_value) {
+ r = initial_value->countChildren();
+ c = (int) ::sqrt(r) + 4;
+ if(r % c > 0) {
+ r = r / c + 1;
+ } else {
+ r = r / c;
+ }
+ } else {
+ c = 4;
+ r = 4;
+ }
+ } else if(initial_value) {
+ c = initial_value->columns();
+ r = initial_value->rows();
+ }
+
+ rowsBox->setValue(r);
+ columnsBox->setValue(c);
+ elementsTable->setNumRows(r);
+ elementsTable->setNumCols(c);
+
+ int timeout;
+ if(initial_value) timeout = 3000 / (r * c);
+ else timeout = 3000;
+ printops.can_display_unicode_string_arg = (void*) elementsTable;
+ for(int index_r = 0; index_r < r; index_r++) {
+ for(int index_c = 0; index_c < c; index_c++) {
+ if(create_vector) {
+ if(initial_value && index_r * c + index_c < (int) initial_value->countChildren()) {
+ if(is_text_struct) elementsTable->setText(index_r, index_c, initial_value->getChild(index_r * c + index_c + 1)->symbol().c_str());
+ else elementsTable->setText(index_r, index_c, initial_value->getChild(index_r * c + index_c + 1)->print(printops).c_str());
+ } else {
+ elementsTable->setText(index_r, index_c, "");
+ }
+ } else {
+ if(initial_value) {
+ if(is_text_struct) elementsTable->setText(index_r, index_c, initial_value->getElement(index_r + 1, index_c + 1)->symbol().c_str());
+ else elementsTable->setText(index_r, index_c, initial_value->getElement(index_r + 1, index_c + 1)->print(printops).c_str());
+ } else {
+ elementsTable->setText(index_r, index_c, "0");
+ }
+ }
+ }
+ }
+ printops.can_display_unicode_string_arg = NULL;
+ matrixstr = "";
+
+ onSelectionChanged();
+
+ exec();
+
+ return matrixstr;
+}
+
+#if QT_VERSION >= 0x030200
+QalculateInsertMatrixTableItem::QalculateInsertMatrixTableItem(QTable *table) : QTableItem(table, QTableItem::OnTyping) {}
+#else
+QalculateInsertMatrixTableItem::QalculateInsertMatrixTableItem(QTable *table) : QTableItem(table, QTableItem::OnTyping, QString::null) {}
+#endif
+QalculateInsertMatrixTableItem::QalculateInsertMatrixTableItem(QTable *table, const QString & text) : QTableItem(table, QTableItem::OnTyping, text) {}
+
+int QalculateInsertMatrixTableItem::alignment() const {return Qt::AlignRight;}
+
+#include "qalculateinsertmatrixvectordialog.moc"
+
diff --git a/src/qalculateinsertmatrixvectordialog.h b/src/qalculateinsertmatrixvectordialog.h
new file mode 100644
index 0000000..32ba4ea
--- /dev/null
+++ b/src/qalculateinsertmatrixvectordialog.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEINSERTMATRIXVECTORDIALOG_H
+#define QALCULATEINSERTMATRIXVECTORDIALOG_H
+
+#include <kdialogbase.h>
+
+class QTable;
+class QLabel;
+class QSpinBox;
+class QRadioButton;
+class KComboBox;
+class KLineEdit;
+class QPushButton;
+class MathStructure;
+class QalculateEditNamesDialog;
+class KnownVariable;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateInsertMatrixVectorDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateInsertMatrixVectorDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateInsertMatrixVectorDialog();
+
+ QString newMatrix();
+ QString newVector();
+ QString editMatrixVector(const MathStructure *initial_value = NULL, bool create_vector = false, bool is_text_struct = false, bool is_result = false);
+
+ QLabel *elementsLabel;
+ QRadioButton *matrixButton, *vectorButton;
+ QTable *elementsTable;
+ QSpinBox *rowsBox, *columnsBox;
+ QString matrixstr;
+ QPushButton *insertSelectionButton;
+
+public slots:
+
+ void typeChanged(int);
+ void rowsChanged(int);
+ void columnsChanged(int);
+ void onSelectionChanged();
+
+protected slots:
+
+ void slotOk();
+ void insertSelection();
+
+};
+
+#endif
diff --git a/src/qalculateperiodictabledialog.cpp b/src/qalculateperiodictabledialog.cpp
new file mode 100644
index 0000000..1eb07be
--- /dev/null
+++ b/src/qalculateperiodictabledialog.cpp
@@ -0,0 +1,276 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateperiodictabledialog.h"
+#include "qalculate_kde_utils.h"
+#include <klocale.h>
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qtooltip.h>
+#include <qcolor.h>
+#include <qpushbutton.h>
+#include <qvbox.h>
+#include <qgrid.h>
+#include "qalculatebuttonwithdata.h"
+#include <kiconloader.h>
+#include <qfontmetrics.h>
+#include <kactivelabel.h>
+#include <qlineedit.h>
+
+extern PrintOptions printops;
+extern QWidget *expressionWidget;
+
+QalculatePeriodicTableDialog::QalculatePeriodicTableDialog(QWidget *parent, const char *name)
+ : KDialogBase(parent, name, false, i18n("Periodic Table"), Close, Close, true) {
+
+ actionButton(Close)->setAutoDefault(false);
+ actionButton(Close)->setDefault(false);
+
+ grid = new QGridLayout(makeMainWidget(), 11, 20, 0, 1);
+
+ grid->addWidget(new QLabel("1", mainWidget()), 0, 1, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("2", mainWidget()), 0, 2, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("3", mainWidget()), 0, 4, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("4", mainWidget()), 0, 5, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("5", mainWidget()), 0, 6, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("6", mainWidget()), 0, 7, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("7", mainWidget()), 0, 8, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("8", mainWidget()), 0, 9, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("9", mainWidget()), 0, 10, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("10", mainWidget()), 0, 11, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("11", mainWidget()), 0, 12, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("12", mainWidget()), 0, 13, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("13", mainWidget()), 0, 14, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("14", mainWidget()), 0, 15, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("15", mainWidget()), 0, 16, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("16", mainWidget()), 0, 17, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("17", mainWidget()), 0, 18, Qt::AlignHCenter);
+ grid->addWidget(new QLabel("18", mainWidget()), 0, 19, Qt::AlignHCenter);
+
+ grid->addWidget(new QLabel("1 ", mainWidget()), 1, 0, Qt::AlignRight);
+ grid->addWidget(new QLabel("2 ", mainWidget()), 2, 0, Qt::AlignRight);
+ grid->addWidget(new QLabel("3 ", mainWidget()), 3, 0, Qt::AlignRight);
+ grid->addWidget(new QLabel("4 ", mainWidget()), 4, 0, Qt::AlignRight);
+ grid->addWidget(new QLabel("5 ", mainWidget()), 5, 0, Qt::AlignRight);
+ grid->addWidget(new QLabel("6 ", mainWidget()), 6, 0, Qt::AlignRight);
+ grid->addWidget(new QLabel("7 ", mainWidget()), 7, 0, Qt::AlignRight);
+
+ grid->addWidget(new QLabel("*", mainWidget()), 6, 3, Qt::AlignRight);
+ grid->addWidget(new QLabel("**", mainWidget()), 7, 3, Qt::AlignRight);
+ grid->addWidget(new QLabel("*", mainWidget()), 9, 3, Qt::AlignRight);
+ grid->addWidget(new QLabel("**", mainWidget()), 10, 3, Qt::AlignRight);
+ grid->addWidget(new QLabel(" ", mainWidget()), 8, 0);
+
+ DataSet *dc = CALCULATOR->getDataSet("atom");
+ if(!dc) {
+ return;
+ }
+ DataObject *e;
+ QalculateButtonWithData *e_button;
+ QString tip;
+ DataProperty *p_xpos = dc->getProperty("x_pos");
+ DataProperty *p_ypos = dc->getProperty("y_pos");
+ DataProperty *p_weight = dc->getProperty("weight");
+ DataProperty *p_number = dc->getProperty("number");
+ DataProperty *p_symbol = dc->getProperty("symbol");
+ DataProperty *p_class = dc->getProperty("class");
+ DataProperty *p_name = dc->getProperty("name");
+ int x_pos = 0, y_pos = 0, group = 0;
+ QString weight;
+ int w = -1;
+ for(size_t i = 1; i < 120; i++) {
+ e = dc->getObject(i2s(i));
+ if(e) {
+ x_pos = s2i(e->getProperty(p_xpos));
+ y_pos = s2i(e->getProperty(p_ypos));
+ }
+ if(e && x_pos > 0 && x_pos <= 18 && y_pos > 0 && y_pos <= 10) {
+ e_button = new QalculateButtonWithData((void*) e, e->getProperty(p_symbol).c_str(), mainWidget());
+ e_button->setFlat(true);
+ group = s2i(e->getProperty(p_class));
+ switch(group) {
+ case 1: {
+ e_button->setPaletteBackgroundColor(QColor(0xee, 0xcc, 0xee));
+ e_button->setPaletteForegroundColor(QColor(0, 0, 0));
+ break;
+ }
+ case 2: {
+ e_button->setPaletteBackgroundColor(QColor(0xdd, 0xcc, 0xee));
+ e_button->setPaletteForegroundColor(QColor(0, 0, 0));
+ break;
+ }
+ case 3: {
+ e_button->setPaletteBackgroundColor(QColor(0xdd, 0xdd, 0xff));
+ e_button->setPaletteForegroundColor(QColor(0, 0, 0));
+ break;
+ }
+ case 4: {
+ e_button->setPaletteBackgroundColor(QColor(0xdd, 0xee, 0xff));
+ e_button->setPaletteForegroundColor(QColor(0, 0, 0));
+ break;
+ }
+ case 5: {
+ e_button->setPaletteBackgroundColor(QColor(0xcc, 0xee, 0xee));
+ e_button->setPaletteForegroundColor(QColor(0, 0, 0));
+ break;
+ }
+ case 6: {
+ e_button->setPaletteBackgroundColor(QColor(0xbb, 0xff, 0xbb));
+ e_button->setPaletteForegroundColor(QColor(0, 0, 0));
+ break;
+ }
+ case 7: {
+ e_button->setPaletteBackgroundColor(QColor(0xee, 0xff, 0xdd));
+ e_button->setPaletteForegroundColor(QColor(0, 0, 0));
+ break;
+ }
+ case 8: {
+ e_button->setPaletteBackgroundColor(QColor(0xff, 0xff, 0xaa));
+ e_button->setPaletteForegroundColor(QColor(0, 0, 0));
+ break;
+ }
+ case 9: {
+ e_button->setPaletteBackgroundColor(QColor(0xff, 0xdd, 0xaa));
+ e_button->setPaletteForegroundColor(QColor(0, 0, 0));
+ break;
+ }
+ case 10: {
+ e_button->setPaletteBackgroundColor(QColor(0xff, 0xcc, 0xdd));
+ e_button->setPaletteForegroundColor(QColor(0, 0, 0));
+ break;
+ }
+ case 11: {
+ e_button->setPaletteBackgroundColor(QColor(0xaa, 0xee, 0xdd));
+ e_button->setPaletteForegroundColor(QColor(0, 0, 0));
+ break;
+ }
+ }
+ if(w < 0) {
+ w = e_button->fontMetrics().width("Uuo") + 12;
+ }
+ e_button->setFixedWidth(w);
+ e_button->setFixedHeight(w);
+ if(x_pos > 2) {
+ grid->addWidget(e_button, y_pos, x_pos + 1);
+ } else {
+ grid->addWidget(e_button, y_pos, x_pos);
+ }
+ tip = e->getProperty(p_number).c_str();
+ tip += " ";
+ tip += e->getProperty(p_name).c_str();
+ weight = e->getPropertyDisplayString(p_weight).c_str();
+ if(!weight.isEmpty() && weight != "-") {
+ tip += "\n";
+ tip += weight;
+ }
+ QToolTip::add(e_button, tip);
+ QObject::connect(e_button, SIGNAL(clickedWithData(void*)), this, SLOT(showElementInfo(void*)));
+ }
+ }
+
+}
+QalculatePeriodicTableDialog::~QalculatePeriodicTableDialog() {}
+void QalculatePeriodicTableDialog::showElementInfo(void *e) {
+ DataObject *o = (DataObject*) e;
+ QalculateElementInfoDialog *dialog = new QalculateElementInfoDialog(o, this);
+ dialog->show();
+}
+
+QalculateElementInfoDialog::QalculateElementInfoDialog(DataObject *element, QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Element Data"), Close, Close, true) {
+
+ setWFlags(getWFlags() | Qt::WDestructiveClose);
+ e = element;
+ DataSet *ds = e->parentSet();
+ if(!ds) {
+ close();
+ return;
+ }
+ QVBox *vbox = makeVBoxMainWidget();
+ QVBox *vbox2 = new QVBox(vbox);
+ DataProperty *p_number = ds->getProperty("number");
+ DataProperty *p_symbol = ds->getProperty("symbol");
+ DataProperty *p_class = ds->getProperty("class");
+ DataProperty *p_name = ds->getProperty("name");
+ QString str = "<div align=\"right\"><font size=4>"; str += e->getProperty(p_number).c_str(); str += "</font></div>";
+ new KActiveLabel(str, vbox2);
+ str = "<font size=6>"; str += e->getProperty(p_symbol).c_str(); str += "</font>";
+ new KActiveLabel(str, vbox2);
+ str = "<font size=5>"; str += e->getProperty(p_name).c_str(); str += "</font> ";
+ new KActiveLabel(str, vbox2);
+
+ QalculateButtonWithData *button;
+ QGrid *grid = new QGrid(3, Qt::Horizontal, vbox);
+ int group = s2i(e->getProperty(p_class));
+ if(group > 0) {
+ str = "<b>"; str += i18n("Classification"); str += ":"; str += "</b>";
+ new QLabel(str, grid);
+ switch(group) {
+ case ALKALI_METALS: {str = i18n("Alkali Metal"); break;}
+ case ALKALI_EARTH_METALS: {str = i18n("Alkaline-Earth Metal"); break;}
+ case LANTHANIDES: {str = i18n("Lanthanide"); break;}
+ case ACTINIDES: {str = i18n("Actinide"); break;}
+ case TRANSITION_METALS: {str = i18n("Transition Metal"); break;}
+ case METALS: {str = i18n("Metal"); break;}
+ case METALLOIDS: {str = i18n("Metalloid"); break;}
+ case NONMETALS: {str = i18n("Non-Metal"); break;}
+ case HALOGENS: {str = i18n("Halogen"); break;}
+ case NOBLE_GASES: {str = i18n("Noble Gas"); break;}
+ case TRANSACTINIDES: {str = i18n("Transactinide"); break;}
+ default: {str = i18n("Unknown"); break;}
+ }
+ new KActiveLabel(str, grid);
+ new QFrame(grid);
+ }
+
+ DataPropertyIter it;
+ DataProperty *dp = ds->getFirstProperty(&it);
+ QString sval;
+ while(dp) {
+ if(!dp->isHidden() && dp != p_number && dp != p_class && dp != p_symbol && dp != p_name) {
+ sval = e->getPropertyDisplayString(dp).c_str();
+ if(!sval.isEmpty()) {
+ str = "<b>"; str += dp->title().c_str(); str += ":"; str += "</b>";
+ new QLabel(str, grid);
+ new KActiveLabel(sval, grid);
+ button = new QalculateButtonWithData((void*) dp, QIconSet(SmallIcon("editpaste")), "", grid);
+ QObject::connect(button, SIGNAL(clickedWithData(void*)), SLOT(insertElementData(void*)));
+ }
+ }
+ dp = ds->getNextProperty(&it);
+ }
+}
+QalculateElementInfoDialog::~QalculateElementInfoDialog() {}
+
+void QalculateElementInfoDialog::insertElementData(void *data) {
+ DataProperty *dp = (DataProperty*) data;
+ DataSet *ds = dp->parentSet();
+ if(ds) {
+ QString str = ds->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionWidget).name.c_str();
+ str += "(";
+ str += e->getProperty(ds->getPrimaryKeyProperty()).c_str();
+ str += CALCULATOR->getComma().c_str();
+ str += " ";
+ str += dp->getName().c_str();
+ str += ")";
+ insert_text_in_expression(str);
+ }
+}
+
+
+#include "qalculateperiodictabledialog.moc"
diff --git a/src/qalculateperiodictabledialog.h b/src/qalculateperiodictabledialog.h
new file mode 100644
index 0000000..5d52767
--- /dev/null
+++ b/src/qalculateperiodictabledialog.h
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEPERIODICTABLEDIALOG_H
+#define QALCULATEPERIODICTABLEDIALOG_H
+
+#include <kdialogbase.h>
+#include <qpushbutton.h>
+
+class QGridLayout;
+class DataObject;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculatePeriodicTableDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculatePeriodicTableDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculatePeriodicTableDialog();
+
+ QGridLayout *grid;
+
+public slots:
+
+ void showElementInfo(void*);
+
+};
+
+class QalculateElementInfoDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateElementInfoDialog(DataObject *element, QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateElementInfoDialog();
+
+ DataObject *e;
+
+public slots:
+
+ void insertElementData(void*);
+
+};
+
+#endif
diff --git a/src/qalculateplotdialog.cpp b/src/qalculateplotdialog.cpp
new file mode 100644
index 0000000..e1adbae
--- /dev/null
+++ b/src/qalculateplotdialog.cpp
@@ -0,0 +1,789 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateplotdialog.h"
+#include "qalculateexpressionedit.h"
+
+#include <klineedit.h>
+#include <kpushbutton.h>
+#include <kcombobox.h>
+#include <qlabel.h>
+#include <klocale.h>
+#include <qcheckbox.h>
+#include <qradiobutton.h>
+#include <qbuttongroup.h>
+#include <qspinbox.h>
+#include <kmessagebox.h>
+#include <qlayout.h>
+#include <ktextedit.h>
+#include <klistview.h>
+#include <kdeversion.h>
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+#include <qtabwidget.h>
+#else
+#include <ktabwidget.h>
+#endif
+#include <kfiledialog.h>
+#include <kapplication.h>
+#include <kstdguiitem.h>
+
+extern PlotLegendPlacement default_plot_legend_placement;
+extern bool default_plot_display_grid;
+extern bool default_plot_full_border;
+extern QString default_plot_min;
+extern QString default_plot_max;
+extern QString default_plot_step;
+extern int default_plot_sampling_rate;
+extern bool default_plot_use_sampling_rate;
+extern bool default_plot_rows;
+extern int default_plot_type;
+extern PlotStyle default_plot_style;
+extern PlotSmoothing default_plot_smoothing;
+extern QString default_plot_variable;
+extern bool default_plot_color;
+extern bool enable_plot_expression_completion;
+
+extern EvaluationOptions evalops;
+
+QalculatePlotDialog::QalculatePlotDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Plot"), User1 | Close | Help, Close, false, KStdGuiItem::save()) {
+
+ actionButton(Close)->setAutoDefault(false);
+ actionButton(Close)->setDefault(false);
+ actionButton(User1)->setAutoDefault(false);
+ actionButton(User1)->setDefault(false);
+
+ actionButton(User1)->setEnabled(false);
+
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ tabs = new QTabWidget(this);
+#else
+ tabs = new KTabWidget(this);
+#endif
+ setMainWidget(tabs);
+ QWidget *page1 = new QWidget(this);
+ QWidget *page2 = new QWidget(this);
+ QWidget *page3 = new QWidget(this);
+ tabs->addTab(page1, i18n("Data"));
+ tabs->addTab(page2, i18n("Function Range"));
+ tabs->addTab(page3, i18n("Appearance"));
+ QGridLayout *grid = new QGridLayout(page1, 1, 1, spacingHint());
+ grid->addWidget(new QLabel(i18n("Title:"), page1), 0, 0);
+ seriesTitleEdit = new KLineEdit(page1);
+ grid->addWidget(seriesTitleEdit, 0, 1);
+ grid->addWidget(new QLabel(i18n("Expression:"), page1), 1, 0);
+ expressionEdit = new QalculateExpressionEdit(false, page1);
+ if(!enable_plot_expression_completion) expressionEdit->disableCompletion();
+ expressionEdit->updateCompletion();
+ grid->addWidget(expressionEdit, 1, 1);
+ QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 2, 2, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ typeGroup = new QButtonGroup();
+ functionButton = new QRadioButton(i18n("Function"), page1);
+ typeGroup->insert(functionButton, 0);
+ hbox->addWidget(functionButton);
+ vectorMatrixButton = new QRadioButton(i18n("Vector/matrix"), page1);
+ typeGroup->insert(vectorMatrixButton, 1);
+ hbox->addWidget(vectorMatrixButton);
+ pairedMatrixButton = new QRadioButton(i18n("Paired matrix"), page1);
+ typeGroup->insert(pairedMatrixButton, 2);
+ hbox->addWidget(pairedMatrixButton);
+ rowsButton = new QCheckBox(i18n("Rows"), page1);
+ hbox->addWidget(rowsButton);
+ xVariableLabel = new QLabel(i18n("X variable:"), page1);
+ grid->addWidget(xVariableLabel, 3, 0);
+ xVariableEdit = new KLineEdit(page1);
+ grid->addWidget(xVariableEdit, 3, 1);
+ grid->addWidget(new QLabel(i18n("Style:"), page1), 4, 0);
+ styleCombo = new KComboBox(page1);
+ styleCombo->insertItem(i18n("Line"));
+ styleCombo->insertItem(i18n("Points"));
+ styleCombo->insertItem(i18n("Line with points"));
+ styleCombo->insertItem(i18n("Boxes/bars"));
+ styleCombo->insertItem(i18n("Histogram"));
+ styleCombo->insertItem(i18n("Steps"));
+ styleCombo->insertItem(i18n("Candlesticks"));
+ styleCombo->insertItem(i18n("Dots"));
+ grid->addWidget(styleCombo, 4, 1);
+ grid->addWidget(new QLabel(i18n("Smoothing:"), page1), 5, 0);
+ smoothingCombo = new KComboBox(page1);
+ smoothingCombo->insertItem(i18n("None"));
+ smoothingCombo->insertItem(i18n("Monotonic"));
+ smoothingCombo->insertItem(i18n("Natural cubic splines"));
+ smoothingCombo->insertItem(i18n("Bezier"));
+ smoothingCombo->insertItem(i18n("Bezier (monotonic)"));
+ grid->addWidget(smoothingCombo, 5, 1);
+ grid->addWidget(new QLabel(i18n("Y-axis:"), page1), 6, 0);
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addLayout(hbox, 6, 1);
+ QButtonGroup *group = new QButtonGroup();
+ primaryButton = new QRadioButton(i18n("Primary"), page1);
+ group->insert(primaryButton, 0);
+ hbox->addWidget(primaryButton);
+ secondaryButton = new QRadioButton(i18n("Secondary"), page1);
+ group->insert(secondaryButton, 1);
+ hbox->addWidget(secondaryButton);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 7, 7, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ addButton = new QPushButton(i18n("Add"), page1);
+ hbox->addWidget(addButton);
+ modifyButton = new QPushButton(i18n("Modify"), page1);
+ hbox->addWidget(modifyButton);
+ removeButton = new QPushButton(i18n("Remove"), page1);
+ hbox->addWidget(removeButton);
+ seriesView = new KListView(page1);
+ seriesView->addColumn(i18n("Title"));
+ seriesView->addColumn(i18n("Expression"));
+ seriesView->setRootIsDecorated(false);
+ seriesView->setItemsRenameable(true);
+ seriesView->setRenameable(0, true);
+ seriesView->setRenameable(1, true);
+ seriesView->setItemsMovable(true);
+ seriesView->setSorting(-1);
+ grid->addMultiCellWidget(seriesView, 8, 8, 0, 1);
+
+ grid = new QGridLayout(page2, 1, 1, spacingHint());
+ grid->addWidget(new QLabel(i18n("Min:"), page2), 0, 0);
+ minEdit = new KLineEdit(page2);
+ grid->addWidget(minEdit, 0, 1);
+ grid->addWidget(new QLabel(i18n("Max:"), page2), 1, 0);
+ maxEdit = new KLineEdit(page2);
+ grid->addWidget(maxEdit, 1, 1);
+ rangeGroup = new QButtonGroup();
+ samplingRateButton = new QRadioButton(i18n("Sampling rate:"), page2);
+ rangeGroup->insert(samplingRateButton, 0);
+ grid->addWidget(samplingRateButton, 2, 0);
+ samplingRateBox = new QSpinBox(1, 10000, 10, page2);
+ grid->addWidget(samplingRateBox, 2, 1);
+ stepSizeButton = new QRadioButton(i18n("Step size:"), page2);
+ rangeGroup->insert(stepSizeButton, 1);
+ grid->addWidget(stepSizeButton, 3, 0);
+ stepSizeEdit = new KLineEdit(page2);
+ grid->addWidget(stepSizeEdit, 3, 1);
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 4, 4, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ applyRangeButton = new KPushButton(KStdGuiItem::apply(), page2);
+ hbox->addWidget(applyRangeButton);
+ grid->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 5, 0);
+
+ grid = new QGridLayout(page3, 1, 1, spacingHint());
+ grid->addWidget(new QLabel(i18n("Title:"), page3), 0, 0);
+ titleEdit = new KLineEdit(page3);
+ grid->addWidget(titleEdit, 0, 1);
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
+ gridButton = new QCheckBox(i18n("Display grid"), page3);
+ hbox->addWidget(gridButton);
+ fullBorderButton = new QCheckBox(i18n("Display full border"), page3);
+ hbox->addWidget(fullBorderButton);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ logXButton = new QCheckBox(i18n("Logarithmic x scale:"), page3);
+ grid->addWidget(logXButton, 2, 0);
+ logXBox = new QSpinBox(2, 100, 1, page3);
+ grid->addWidget(logXBox, 2, 1);
+ logYButton = new QCheckBox(i18n("Logarithmic y scale:"), page3);
+ grid->addWidget(logYButton, 3, 0);
+ logYBox = new QSpinBox(2, 100, 1, page3);
+ grid->addWidget(logYBox, 3, 1);
+ grid->addWidget(new QLabel(i18n("X-axis label:"), page3), 4, 0);
+ xLabelEdit = new KLineEdit(page3);
+ grid->addWidget(xLabelEdit, 4, 1);
+ grid->addWidget(new QLabel(i18n("Y-axis label:"), page3), 5, 0);
+ yLabelEdit = new KLineEdit(page3);
+ grid->addWidget(yLabelEdit, 5, 1);
+ grid->addWidget(new QLabel(i18n("Color display:"), page3), 6, 0);
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addLayout(hbox, 6, 1);
+ group = new QButtonGroup();
+ colorButton = new QRadioButton(i18n("Color"), page3);
+ group->insert(colorButton, 0);
+ hbox->addWidget(colorButton);
+ monochromeButton = new QRadioButton(i18n("Monochrome"), page3);
+ group->insert(monochromeButton, 1);
+ hbox->addWidget(monochromeButton);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ grid->addWidget(new QLabel(i18n("Legend placement:"), page3), 7, 0);
+ legendPlacementCombo = new KComboBox(page3);
+ legendPlacementCombo->insertItem(i18n("Hide"));
+ legendPlacementCombo->insertItem(i18n("Top-left"));
+ legendPlacementCombo->insertItem(i18n("Top-right"));
+ legendPlacementCombo->insertItem(i18n("Bottom-left"));
+ legendPlacementCombo->insertItem(i18n("Bottom-right"));
+ legendPlacementCombo->insertItem(i18n("Below"));
+ legendPlacementCombo->insertItem(i18n("Outside"));
+ grid->addWidget(legendPlacementCombo, 7, 1);
+ hbox = new QHBoxLayout(0, 0, spacingHint());
+ grid->addMultiCellLayout(hbox, 8, 8, 0, 1);
+ hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
+ applyAppearanceButton = new KPushButton(KStdGuiItem::apply(), page3);
+ hbox->addWidget(applyAppearanceButton);
+ grid->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 9, 0);
+
+ primaryButton->setChecked(true);
+ modifyButton->setEnabled(false);
+ removeButton->setEnabled(false);
+ gridButton->setChecked(default_plot_display_grid);
+ fullBorderButton->setChecked(default_plot_full_border);
+ rowsButton->setChecked(default_plot_rows);
+ colorButton->setChecked(default_plot_color);
+ monochromeButton->setChecked(!default_plot_color);
+ minEdit->setText(default_plot_min);
+ maxEdit->setText(default_plot_max);
+ stepSizeEdit->setText(default_plot_step);
+ xVariableEdit->setText(default_plot_variable);
+ samplingRateButton->setChecked(default_plot_use_sampling_rate);
+ samplingRateBox->setEnabled(default_plot_use_sampling_rate);
+ stepSizeButton->setChecked(!default_plot_use_sampling_rate);
+ stepSizeEdit->setEnabled(!default_plot_use_sampling_rate);
+ logXBox->setEnabled(false);
+ logYBox->setEnabled(false);
+ switch(default_plot_type) {
+ case 1: {vectorMatrixButton->setChecked(true); break;}
+ case 2: {pairedMatrixButton->setChecked(true); break;}
+ default: {functionButton->setChecked(true);}
+ }
+ rowsButton->setEnabled(default_plot_type == 1 || default_plot_type == 2);
+ xVariableEdit->setEnabled(default_plot_type != 1 && default_plot_type != 2);
+ xVariableLabel->setEnabled(default_plot_type != 1 && default_plot_type != 2);
+ switch(default_plot_legend_placement) {
+ case PLOT_LEGEND_NONE: {legendPlacementCombo->setCurrentItem(0); break;}
+ case PLOT_LEGEND_TOP_LEFT: {legendPlacementCombo->setCurrentItem(1); break;}
+ case PLOT_LEGEND_TOP_RIGHT: {legendPlacementCombo->setCurrentItem(2); break;}
+ case PLOT_LEGEND_BOTTOM_LEFT: {legendPlacementCombo->setCurrentItem(3); break;}
+ case PLOT_LEGEND_BOTTOM_RIGHT: {legendPlacementCombo->setCurrentItem(4); break;}
+ case PLOT_LEGEND_BELOW: {legendPlacementCombo->setCurrentItem(5); break;}
+ case PLOT_LEGEND_OUTSIDE: {legendPlacementCombo->setCurrentItem(6); break;}
+ }
+ switch(default_plot_smoothing) {
+ case PLOT_SMOOTHING_NONE: {smoothingCombo->setCurrentItem(0); break;}
+ case PLOT_SMOOTHING_UNIQUE: {smoothingCombo->setCurrentItem(1); break;}
+ case PLOT_SMOOTHING_CSPLINES: {smoothingCombo->setCurrentItem(2); break;}
+ case PLOT_SMOOTHING_BEZIER: {smoothingCombo->setCurrentItem(3); break;}
+ case PLOT_SMOOTHING_SBEZIER: {smoothingCombo->setCurrentItem(4); break;}
+ }
+ switch(default_plot_style) {
+ case PLOT_STYLE_LINES: {styleCombo->setCurrentItem(0); break;}
+ case PLOT_STYLE_POINTS: {styleCombo->setCurrentItem(1); break;}
+ case PLOT_STYLE_POINTS_LINES: {styleCombo->setCurrentItem(2); break;}
+ case PLOT_STYLE_BOXES: {styleCombo->setCurrentItem(3); break;}
+ case PLOT_STYLE_HISTOGRAM: {styleCombo->setCurrentItem(4); break;}
+ case PLOT_STYLE_STEPS: {styleCombo->setCurrentItem(5); break;}
+ case PLOT_STYLE_CANDLESTICKS: {styleCombo->setCurrentItem(6); break;}
+ case PLOT_STYLE_DOTS: {styleCombo->setCurrentItem(7); break;}
+ }
+ samplingRateBox->setValue(default_plot_sampling_rate);
+
+ seriesTitleEdit->setFocus();
+
+ connect(seriesTitleEdit, SIGNAL(returnPressed()), expressionEdit, SLOT(setFocus()));
+ connect(expressionEdit, SIGNAL(returnPressed()), this, SLOT(expressionActivated()));
+ connect(typeGroup, SIGNAL(clicked(int)), this, SLOT(typeChanged(int)));
+ connect(rangeGroup, SIGNAL(clicked(int)), this, SLOT(rangeTypeChanged(int)));
+ connect(logXButton, SIGNAL(toggled(bool)), logXBox, SLOT(setEnabled(bool)));
+ connect(logYButton, SIGNAL(toggled(bool)), logYBox, SLOT(setEnabled(bool)));
+ connect(applyRangeButton, SIGNAL(clicked()), this, SLOT(applyRange()));
+ connect(applyAppearanceButton, SIGNAL(clicked()), this, SLOT(applyAppearance()));
+ connect(seriesView, SIGNAL(selectionChanged()), this, SLOT(seriesSelected()));
+ connect(seriesView, SIGNAL(itemRenamed(QListViewItem*, const QString&, int)), this, SLOT(seriesItemRenamed(QListViewItem*, const QString&, int)));
+ connect(addButton, SIGNAL(clicked()), this, SLOT(addSeries()));
+ connect(modifyButton, SIGNAL(clicked()), this, SLOT(modifySeries()));
+ connect(removeButton, SIGNAL(clicked()), this, SLOT(removeSeries()));
+ connect(this, SIGNAL(user1Clicked()), this, SLOT(savePlot()));
+ connect(this, SIGNAL(finished()), this, SLOT(onClosing()));
+
+}
+
+QalculatePlotDialog::~QalculatePlotDialog() {}
+
+void QalculatePlotDialog::slotHelp() {
+ KApplication::kApplication()->invokeHelp("qalculate-plotting");
+}
+
+void QalculatePlotDialog::saveMode() {
+
+ enable_plot_expression_completion = expressionEdit->completionEnabled();
+ default_plot_display_grid = gridButton->isChecked();
+ default_plot_full_border = fullBorderButton->isChecked();
+ default_plot_rows = rowsButton->isChecked();
+ default_plot_color = colorButton->isChecked();
+ default_plot_min = minEdit->text().ascii();
+ default_plot_max = maxEdit->text().ascii();
+ default_plot_step = stepSizeEdit->text().ascii();
+ default_plot_variable = xVariableEdit->text().ascii();
+ default_plot_use_sampling_rate = samplingRateButton->isChecked();
+ if(vectorMatrixButton->isChecked()) {
+ default_plot_type = 1;
+ } else if(pairedMatrixButton->isChecked()) {
+ default_plot_type = 2;
+ } else {
+ default_plot_type = 0;
+ }
+ switch(legendPlacementCombo->currentItem()) {
+ case 0: {default_plot_legend_placement = PLOT_LEGEND_NONE; break;}
+ case 1: {default_plot_legend_placement = PLOT_LEGEND_TOP_LEFT; break;}
+ case 2: {default_plot_legend_placement = PLOT_LEGEND_TOP_RIGHT; break;}
+ case 3: {default_plot_legend_placement = PLOT_LEGEND_BOTTOM_LEFT; break;}
+ case 4: {default_plot_legend_placement = PLOT_LEGEND_BOTTOM_RIGHT; break;}
+ case 5: {default_plot_legend_placement = PLOT_LEGEND_BELOW; break;}
+ case 6: {default_plot_legend_placement = PLOT_LEGEND_OUTSIDE; break;}
+ }
+ switch(smoothingCombo->currentItem()) {
+ case 0: {default_plot_smoothing = PLOT_SMOOTHING_NONE; break;}
+ case 1: {default_plot_smoothing = PLOT_SMOOTHING_UNIQUE; break;}
+ case 2: {default_plot_smoothing = PLOT_SMOOTHING_CSPLINES; break;}
+ case 3: {default_plot_smoothing = PLOT_SMOOTHING_BEZIER; break;}
+ case 4: {default_plot_smoothing = PLOT_SMOOTHING_SBEZIER; break;}
+ }
+ switch(styleCombo->currentItem()) {
+ case 0: {default_plot_style = PLOT_STYLE_LINES; break;}
+ case 1: {default_plot_style = PLOT_STYLE_POINTS; break;}
+ case 2: {default_plot_style = PLOT_STYLE_POINTS_LINES; break;}
+ case 3: {default_plot_style = PLOT_STYLE_BOXES; break;}
+ case 4: {default_plot_style = PLOT_STYLE_HISTOGRAM; break;}
+ case 5: {default_plot_style = PLOT_STYLE_STEPS; break;}
+ case 6: {default_plot_style = PLOT_STYLE_CANDLESTICKS; break;}
+ case 7: {default_plot_style = PLOT_STYLE_DOTS; break;}
+ }
+ default_plot_sampling_rate = samplingRateBox->value();
+}
+void QalculatePlotDialog::onClosing() {
+
+ tabs->setCurrentPage(0);
+ modifyButton->setEnabled(false);
+ removeButton->setEnabled(false);
+ actionButton(User1)->setEnabled(false);
+
+ QListViewItemIterator it(seriesView);
+ while(it.current()) {
+ MathStructure *y_vector = itemYVector[it.current()], *x_vector = itemXVector[it.current()];
+ if(y_vector) delete y_vector;
+ if(x_vector) delete x_vector;
+ ++it;
+ }
+ itemStyle.clear();
+ itemType.clear();
+ itemAxis.clear();
+ itemSmoothing.clear();
+ itemRows.clear();
+ itemXVector.clear();
+ itemYVector.clear();
+ itemXVariable.clear();
+ seriesView->clear();
+ expressionEdit->clear();
+ seriesTitleEdit->clear();
+
+ CALCULATOR->closeGnuplot();
+
+}
+void QalculatePlotDialog::seriesItemRenamed(QListViewItem *i, const QString &str, int col) {
+ if(!i) return;
+ if(col == 0) {
+ updatePlot();
+ } else if(col == 1) {
+ if(str.isEmpty()) {
+ KMessageBox::error(this, i18n("Empty expression."));
+ }
+ MathStructure *x_vector = itemXVector[i], *y_vector = itemYVector[i];
+ if(x_vector) delete x_vector;
+ if(y_vector) delete y_vector;
+ x_vector = NULL;
+ y_vector = NULL;
+ generatePlotSeries(&x_vector, &y_vector, itemType[i], str.ascii(), itemXVariable[i].ascii());
+ itemXVector[i] = x_vector;
+ itemYVector[i] = y_vector;
+ updatePlot();
+ }
+ seriesSelected();
+}
+void QalculatePlotDialog::seriesSelected() {
+ QListViewItem *i = seriesView->selectedItem();
+ if(i) {
+ modifyButton->setEnabled(true);
+ removeButton->setEnabled(true);
+ expressionEdit->setText(i->text(1));
+ seriesTitleEdit->setText(i->text(0));
+ xVariableEdit->setText(itemXVariable[i]);
+ styleCombo->setCurrentItem(itemStyle[i]);
+ smoothingCombo->setCurrentItem(itemSmoothing[i]);
+ typeGroup->setButton(itemType[i]);
+ secondaryButton->setChecked(itemAxis[i] == 2);
+ primaryButton->setChecked(itemAxis[i] != 2);
+ rowsButton->setChecked(itemRows[i]);
+ } else {
+ modifyButton->setEnabled(false);
+ removeButton->setEnabled(false);
+ }
+}
+void QalculatePlotDialog::rangeTypeChanged(int i) {
+ stepSizeEdit->setEnabled(i == 1);
+ samplingRateBox->setEnabled(i == 0);
+}
+
+void QalculatePlotDialog::typeChanged(int i) {
+ rowsButton->setEnabled(i == 1 || i == 2);
+ xVariableEdit->setEnabled(i != 1 && i != 2);
+ xVariableLabel->setEnabled(i != 1 && i != 2);
+}
+void QalculatePlotDialog::expressionActivated() {
+ QListViewItem *i = seriesView->selectedItem();
+ if(i) {
+ modifySeries();
+ } else {
+ addSeries();
+ }
+}
+void QalculatePlotDialog::addSeries() {
+ QString expression = expressionEdit->text();
+ if(expression.stripWhiteSpace().isEmpty()) {
+ expressionEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty expression."));
+ return;
+ }
+ int type = 0, axis = 1;
+ bool rows = false;
+ QString title = seriesTitleEdit->text();
+ if(vectorMatrixButton->isChecked()) {
+ type = 1;
+ } else if(pairedMatrixButton->isChecked()) {
+ type = 2;
+ }
+ QString str_x = xVariableEdit->text().stripWhiteSpace();
+ if(str_x.isEmpty() && type == 0) {
+ xVariableEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty x variable."));
+ return;
+ }
+ expressionEdit->addToHistory(expression);
+ if(secondaryButton->isChecked()) {
+ axis = 2;
+ }
+ if((type == 1 || type == 2) && title.isEmpty()) {
+ Variable *v = CALCULATOR->getActiveVariable(expression.ascii());
+ if(v) {
+ title = v->title(false).c_str();
+ }
+ }
+ MathStructure *x_vector, *y_vector;
+ generatePlotSeries(&x_vector, &y_vector, type, expression.ascii(), str_x.ascii());
+ rows = rowsButton->isChecked();
+ QListViewItem *i = new KListViewItem(seriesView, seriesView->lastChild(), title, expression);
+ itemStyle[i] = styleCombo->currentItem();
+ itemSmoothing[i] = smoothingCombo->currentItem();
+ itemType[i] = type;
+ itemAxis[i] = axis;
+ itemRows[i] = rows;
+ itemXVector[i] = x_vector;
+ itemYVector[i] = y_vector;
+ itemXVariable[i] = str_x;
+ seriesView->setSelected(i, true);
+ updatePlot();
+}
+void QalculatePlotDialog::modifySeries() {
+ QListViewItem *i = seriesView->selectedItem();
+ if(i) {
+ QString expression = expressionEdit->text();
+ if(expression.stripWhiteSpace().isEmpty()) {
+ expressionEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty expression."));
+ return;
+ }
+ int type = 0, axis = 1;
+ QString title = seriesTitleEdit->text();
+ if(vectorMatrixButton->isChecked()) {
+ type = 1;
+ } else if(pairedMatrixButton->isChecked()) {
+ type = 2;
+ }
+ QString str_x = xVariableEdit->text().stripWhiteSpace();
+ if(str_x.isEmpty() && type == 0) {
+ xVariableEdit->setFocus();
+ KMessageBox::error(this, i18n("Empty x variable."));
+ return;
+ }
+ expressionEdit->addToHistory(expression);
+ if(secondaryButton->isChecked()) {
+ axis = 2;
+ }
+ if((type == 1 || type == 2) && title.isEmpty()) {
+ Variable *v = CALCULATOR->getActiveVariable(expression.ascii());
+ if(v) {
+ title = v->title(false).c_str();
+ }
+ }
+ MathStructure *x_vector = itemXVector[i], *y_vector = itemYVector[i];
+ if(x_vector) delete x_vector;
+ if(y_vector) delete y_vector;
+ x_vector = NULL;
+ y_vector = NULL;
+ generatePlotSeries(&x_vector, &y_vector, type, expression.ascii(), str_x.ascii());
+ i->setText(0, title);
+ i->setText(1, expression);
+ itemStyle[i] = styleCombo->currentItem();
+ itemSmoothing[i] = smoothingCombo->currentItem();
+ itemType[i] = type;
+ itemAxis[i] = axis;
+ itemRows[i] = rowsButton->isChecked();
+ itemXVector[i] = x_vector;
+ itemYVector[i] = y_vector;
+ itemXVariable[i] = str_x;
+ updatePlot();
+ }
+}
+void QalculatePlotDialog::removeSeries() {
+ QListViewItem *i = seriesView->selectedItem();
+ if(i) {
+ MathStructure *x_vector = itemXVector[i], *y_vector = itemYVector[i];
+ if(x_vector) delete x_vector;
+ if(y_vector) delete y_vector;
+ itemStyle.erase(i);
+ itemSmoothing.erase(i);
+ itemType.erase(i);
+ itemAxis.erase(i);
+ itemRows.erase(i);
+ itemXVector.erase(i);
+ itemYVector.erase(i);
+ itemXVariable.erase(i);
+ delete i;
+ expressionEdit->clear();
+ seriesTitleEdit->clear();
+ updatePlot();
+ }
+}
+void QalculatePlotDialog::applyRange() {
+ QListViewItemIterator it(seriesView);
+ while(it.current()) {
+ MathStructure *x_vector = itemXVector[it.current()], *y_vector = itemYVector[it.current()];
+ if(y_vector) delete y_vector;
+ if(x_vector) delete x_vector;
+ x_vector = NULL;
+ y_vector = NULL;
+ generatePlotSeries(&x_vector, &y_vector, itemType[it.current()], it.current()->text(1).ascii(), itemXVariable[it.current()].ascii());
+ itemXVector[it.current()] = x_vector;
+ itemYVector[it.current()] = y_vector;
+ ++it;
+ }
+ updatePlot();
+}
+void QalculatePlotDialog::applyAppearance() {
+ updatePlot();
+}
+
+bool QalculatePlotDialog::generatePlot(PlotParameters &pp, vector<MathStructure> &y_vectors, vector<MathStructure> &x_vectors, vector<PlotDataParameters*> &pdps) {
+ QListViewItemIterator it(seriesView);
+ if(!it.current()) {
+ return false;
+ }
+ while(it.current()) {
+ int count = 1;
+ QString title = it.current()->text(0), expression = it.current()->text(1);
+ int style = itemStyle[it.current()];
+ int smoothing = itemSmoothing[it.current()];
+ int type = itemType[it.current()];
+ int axis = itemAxis[it.current()];
+ bool rows = itemRows[it.current()];
+ MathStructure *x_vector = itemXVector[it.current()];
+ MathStructure *y_vector = itemYVector[it.current()];
+ if(type == 1) {
+ if(y_vector->isMatrix()) {
+ count = 0;
+ if(rows) {
+ for(size_t i = 1; i <= y_vector->rows(); i++) {
+ y_vectors.push_back(m_undefined);
+ y_vector->rowToVector(i, y_vectors[y_vectors.size() - 1]);
+ x_vectors.push_back(m_undefined);
+ count++;
+ }
+ } else {
+ for(size_t i = 1; i <= y_vector->columns(); i++) {
+ y_vectors.push_back(m_undefined);
+ y_vector->columnToVector(i, y_vectors[y_vectors.size() - 1]);
+ x_vectors.push_back(m_undefined);
+ count++;
+ }
+ }
+ } else if(y_vector->isVector()) {
+ y_vectors.push_back(*y_vector);
+ x_vectors.push_back(m_undefined);
+ } else {
+ y_vectors.push_back(*y_vector);
+ y_vectors[y_vectors.size() - 1].transform(STRUCT_VECTOR);
+ x_vectors.push_back(m_undefined);
+ }
+ } else if(type == 2) {
+ if(y_vector->isMatrix()) {
+ count = 0;
+ if(rows) {
+ for(size_t i = 1; i <= y_vector->rows(); i += 2) {
+ y_vectors.push_back(m_undefined);
+ y_vector->rowToVector(i, y_vectors[y_vectors.size() - 1]);
+ x_vectors.push_back(m_undefined);
+ y_vector->rowToVector(i + 1, x_vectors[x_vectors.size() - 1]);
+ count++;
+ }
+ } else {
+ for(size_t i = 1; i <= y_vector->columns(); i += 2) {
+ y_vectors.push_back(m_undefined);
+ y_vector->columnToVector(i, y_vectors[y_vectors.size() - 1]);
+ x_vectors.push_back(m_undefined);
+ y_vector->columnToVector(i + 1, x_vectors[x_vectors.size() - 1]);
+ count++;
+ }
+ }
+ } else if(y_vector->isVector()) {
+ y_vectors.push_back(*y_vector);
+ x_vectors.push_back(m_undefined);
+ } else {
+ y_vectors.push_back(*y_vector);
+ y_vectors[y_vectors.size() - 1].transform(STRUCT_VECTOR);
+ x_vectors.push_back(m_undefined);
+ }
+ } else {
+ y_vectors.push_back(*y_vector);
+ x_vectors.push_back(*x_vector);
+ }
+ for(int i = 0; i < count; i++) {
+ PlotDataParameters *pdp = new PlotDataParameters();
+ pdp->title = title.ascii();
+ if(count > 1) {
+ pdp->title += " :";
+ pdp->title += i2s(i + 1);
+ }
+ remove_blank_ends(pdp->title);
+ if(pdp->title.empty()) {
+ pdp->title = expression.ascii();
+ }
+ switch(smoothing) {
+ case 0: {pdp->smoothing = PLOT_SMOOTHING_NONE; break;}
+ case 1: {pdp->smoothing = PLOT_SMOOTHING_UNIQUE; break;}
+ case 2: {pdp->smoothing = PLOT_SMOOTHING_CSPLINES; break;}
+ case 3: {pdp->smoothing = PLOT_SMOOTHING_BEZIER; break;}
+ case 4: {pdp->smoothing = PLOT_SMOOTHING_SBEZIER; break;}
+ }
+ switch(style) {
+ case 0: {pdp->style = PLOT_STYLE_LINES; break;}
+ case 1: {pdp->style = PLOT_STYLE_POINTS; break;}
+ case 2: {pdp->style = PLOT_STYLE_POINTS_LINES; break;}
+ case 3: {pdp->style = PLOT_STYLE_DOTS; break;}
+ case 4: {pdp->style = PLOT_STYLE_BOXES; break;}
+ case 5: {pdp->style = PLOT_STYLE_HISTOGRAM; break;}
+ case 6:{pdp->style = PLOT_STYLE_STEPS; break;}
+ case 7: {pdp->style = PLOT_STYLE_CANDLESTICKS; break;}
+ }
+ pdp->yaxis2 = (axis == 2);
+ pdps.push_back(pdp);
+ }
+ ++it;
+ }
+ switch(legendPlacementCombo->currentItem()) {
+ case 0: {pp.legend_placement = PLOT_LEGEND_NONE; break;}
+ case 1: {pp.legend_placement = PLOT_LEGEND_TOP_LEFT; break;}
+ case 2: {pp.legend_placement = PLOT_LEGEND_TOP_RIGHT; break;}
+ case 3: {pp.legend_placement = PLOT_LEGEND_BOTTOM_LEFT; break;}
+ case 4: {pp.legend_placement = PLOT_LEGEND_BOTTOM_RIGHT; break;}
+ case 5: {pp.legend_placement = PLOT_LEGEND_BELOW; break;}
+ case 6: {pp.legend_placement = PLOT_LEGEND_OUTSIDE; break;}
+ }
+ pp.title = titleEdit->text().ascii();
+ pp.x_label = xLabelEdit->text().ascii();
+ pp.y_label = yLabelEdit->text().ascii();
+ pp.grid = gridButton->isChecked();
+ pp.x_log = logXButton->isChecked();
+ pp.y_log = logYButton->isChecked();
+ pp.x_log_base = logXBox->value();
+ pp.y_log_base = logYBox->value();
+ pp.color = colorButton->isChecked();
+ pp.show_all_borders = fullBorderButton->isChecked();
+ return true;
+}
+void QalculatePlotDialog::savePlot() {
+ QString title = titleEdit->text().ascii();
+ if(title.isEmpty()) {
+ title = "plot.png";
+ } else {
+ title += ".png";
+ }
+ QString filename;
+ while(true) {
+ filename = KFileDialog::getSaveFileName(title, "image/png image/svg application/postscript image/x-eps /text/x-tex image/x-xfig", this, i18n("Save Image"));
+ if(filename.isEmpty()) {
+ return;
+ } else {
+ if(QFile::exists(filename)) {
+ 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) {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+ vector<MathStructure> y_vectors;
+ vector<MathStructure> x_vectors;
+ vector<PlotDataParameters*> pdps;
+ PlotParameters pp;
+ if(generatePlot(pp, y_vectors, x_vectors, pdps)) {
+ pp.filename = filename.ascii();
+ pp.filetype = PLOT_FILETYPE_AUTO;
+ CALCULATOR->plotVectors(&pp, y_vectors, x_vectors, pdps);
+ for(size_t i = 0; i < pdps.size(); i++) {
+ if(pdps[i]) delete pdps[i];
+ }
+ }
+}
+void QalculatePlotDialog::updatePlot() {
+ vector<MathStructure> y_vectors;
+ vector<MathStructure> x_vectors;
+ vector<PlotDataParameters*> pdps;
+ PlotParameters pp;
+ if(!generatePlot(pp, y_vectors, x_vectors, pdps)) {
+ CALCULATOR->closeGnuplot();
+ actionButton(User1)->setEnabled(false);
+ return;
+ }
+ CALCULATOR->plotVectors(&pp, y_vectors, x_vectors, pdps);
+ actionButton(User1)->setEnabled(true);
+ for(size_t i = 0; i < pdps.size(); i++) {
+ if(pdps[i]) delete pdps[i];
+ }
+}
+void QalculatePlotDialog::generatePlotSeries(MathStructure **x_vector, MathStructure **y_vector, int type, string str, string str_x) {
+ EvaluationOptions eo;
+ eo.approximation = APPROXIMATION_APPROXIMATE;
+ eo.parse_options = evalops.parse_options;
+ eo.parse_options.read_precision = DONT_READ_PRECISION;
+ if(type == 1 || type == 2) {
+ *y_vector = new MathStructure(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo));
+ *x_vector = NULL;
+ } else {
+ MathStructure min(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(minEdit->text().ascii(), evalops.parse_options), eo));
+ MathStructure max(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(maxEdit->text().ascii(), evalops.parse_options), eo));
+ *x_vector = new MathStructure();
+ (*x_vector)->clearVector();
+ if(stepSizeButton->isChecked()) {
+ *y_vector = new MathStructure(CALCULATOR->expressionToPlotVector(str, min, max, CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(stepSizeEdit->text().ascii(), evalops.parse_options), eo), *x_vector, str_x, evalops.parse_options));
+ } else {
+ *y_vector = new MathStructure(CALCULATOR->expressionToPlotVector(str, min, max, samplingRateBox->value(), *x_vector, str_x, evalops.parse_options));
+ }
+ }
+}
+
+#include "qalculateplotdialog.moc"
diff --git a/src/qalculateplotdialog.h b/src/qalculateplotdialog.h
new file mode 100644
index 0000000..984dad6
--- /dev/null
+++ b/src/qalculateplotdialog.h
@@ -0,0 +1,101 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEPLOTDIALOG_H
+#define QALCULATEPLOTDIALOG_H
+
+#include <kdialogbase.h>
+#include <qmap.h>
+#include <qstring.h>
+
+class KLineEdit;
+class QCheckBox;
+class QRadioButton;
+class QSpinBox;
+class QButtonGroup;
+class KComboBox;
+class QPushButton;
+class QTabWidget;
+class KListView;
+class QLabel;
+class QListViewItem;
+class QalculateExpressionEdit;
+
+#include "qalculate_kde_utils.h"
+
+/**
+@author Niklas Knutsson
+*/
+class QalculatePlotDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculatePlotDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculatePlotDialog();
+
+ QLabel *xVariableLabel;
+ KLineEdit *seriesTitleEdit, *xVariableEdit, *minEdit, *maxEdit, *stepSizeEdit, *titleEdit, *xLabelEdit, *yLabelEdit;
+ QalculateExpressionEdit *expressionEdit;
+ QCheckBox *rowsButton, *gridButton, *fullBorderButton, *logXButton, *logYButton;
+ QRadioButton *functionButton, *vectorMatrixButton, *pairedMatrixButton, *primaryButton, *secondaryButton, *samplingRateButton, *stepSizeButton, *colorButton, *monochromeButton;
+ QSpinBox *samplingRateBox, *logXBox, *logYBox;
+ QButtonGroup *typeGroup, *rangeGroup;
+ KComboBox *styleCombo, *smoothingCombo, *legendPlacementCombo;
+ QPushButton *addButton, *modifyButton, *removeButton, *applyRangeButton, *applyAppearanceButton;
+ QTabWidget *tabs;
+ KListView *seriesView;
+
+ bool generatePlot(PlotParameters &pp, vector<MathStructure> &y_vectors, vector<MathStructure> &x_vectors, vector<PlotDataParameters*> &pdps);
+ void generatePlotSeries(MathStructure **x_vector, MathStructure **y_vector, int type, string str, string str_x);
+
+ QMap<QListViewItem*, int> itemStyle;
+ QMap<QListViewItem*, int> itemSmoothing;
+ QMap<QListViewItem*, int> itemType;
+ QMap<QListViewItem*, int> itemAxis;
+ QMap<QListViewItem*, bool> itemRows;
+ QMap<QListViewItem*, MathStructure*> itemXVector;
+ QMap<QListViewItem*, MathStructure*> itemYVector;
+ QMap<QListViewItem*, QString> itemXVariable;
+
+protected slots:
+
+ void slotHelp();
+
+public slots:
+
+ void onClosing();
+ void seriesItemRenamed(QListViewItem*, const QString&, int);
+ void seriesSelected();
+ void rangeTypeChanged(int);
+ void typeChanged(int);
+ void savePlot();
+ void expressionActivated();
+ void addSeries();
+ void modifySeries();
+ void removeSeries();
+ void applyRange();
+ void applyAppearance();
+ void updatePlot();
+ void saveMode();
+
+};
+
+#endif
diff --git a/src/qalculateprecisiondialog.cpp b/src/qalculateprecisiondialog.cpp
new file mode 100644
index 0000000..d1f6741
--- /dev/null
+++ b/src/qalculateprecisiondialog.cpp
@@ -0,0 +1,54 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateprecisiondialog.h"
+
+#include <qlabel.h>
+#include <qspinbox.h>
+#include <klocale.h>
+#include <qhbox.h>
+#include <kguiitem.h>
+#include <qlayout.h>
+#include <kpushbutton.h>
+#include <kdeversion.h>
+
+QalculatePrecisionDialog::QalculatePrecisionDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Precision"), Apply | Close, Close, true) {
+
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ setButtonApplyText(i18n("Recalculate"));
+#else
+ setButtonApply(KGuiItem(i18n("Recalculate")));
+#endif
+ setMainWidget(new QWidget(this));
+ QHBoxLayout *box = new QHBoxLayout(mainWidget());
+ box->setSpacing(spacingHint());
+ box->addWidget(new QLabel(i18n("Precision:"), mainWidget()));
+ precisionBox = new QSpinBox(1, 100000, 1, mainWidget());
+ precisionBox->setButtonSymbols(QSpinBox::PlusMinus);
+ box->addWidget(precisionBox);
+
+ resize(QSize(300, minimumSizeHint().height()).expandedTo(minimumSizeHint()));
+
+}
+
+
+QalculatePrecisionDialog::~QalculatePrecisionDialog() {}
+
+
+#include "qalculateprecisiondialog.moc"
diff --git a/src/qalculateprecisiondialog.h b/src/qalculateprecisiondialog.h
new file mode 100644
index 0000000..9abc99c
--- /dev/null
+++ b/src/qalculateprecisiondialog.h
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEPRECISIONDIALOG_H
+#define QALCULATEPRECISIONDIALOG_H
+
+#include <kdialogbase.h>
+
+class QSpinBox;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculatePrecisionDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculatePrecisionDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculatePrecisionDialog();
+
+ QSpinBox *precisionBox;
+
+};
+
+#endif
diff --git a/src/qalculatepreferencesdialog.cpp b/src/qalculatepreferencesdialog.cpp
new file mode 100644
index 0000000..a0faeff
--- /dev/null
+++ b/src/qalculatepreferencesdialog.cpp
@@ -0,0 +1,414 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculatepreferencesdialog.h"
+#include "qalculate_kde_utils.h"
+
+#include <klocale.h>
+#include <qbuttongroup.h>
+#include <qcheckbox.h>
+#include <qlabel.h>
+#include <qradiobutton.h>
+#include <qtooltip.h>
+#include <kdeversion.h>
+#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR > 1
+#include <kfontrequester.h>
+#endif
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+#include <qtabwidget.h>
+#else
+#include <ktabwidget.h>
+#endif
+#include <qpushbutton.h>
+#include <qfont.h>
+#include <qpushbutton.h>
+#include <qlayout.h>
+#include <kcolorbutton.h>
+#include "kqalculate.h"
+
+extern KQalculate *mainWin;
+extern PrintOptions printops;
+extern EvaluationOptions evalops;
+extern bool fetch_exchange_rates_at_startup, save_mode_on_exit, save_defs_on_exit;
+extern bool use_custom_result_font, use_custom_expression_font, use_custom_status_font;
+extern QString custom_result_font, custom_expression_font, custom_status_font;
+extern QWidget *expressionWidget, *resultWidget, *statusWidget_l;
+extern bool close_to_systray;
+extern bool display_expression_status;
+extern QColor status_error_color;
+extern QColor status_warning_color;
+extern int use_icon_buttons;
+extern bool rpn_keypad_only;
+
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+#include <kfontdialog.h>
+
+class KFontRequester : public QWidget
+{
+ Q_OBJECT
+
+ public:
+
+ KFontRequester( QWidget *parent=0L, const char *name=0L,
+ bool onlyFixed=false );
+
+ QFont font() const { return m_selFont; }
+ virtual void setFont( const QFont &font, bool onlyFixed=false );
+
+ protected:
+
+ void displaySampleText();
+
+ protected slots:
+
+ virtual void buttonClicked();
+
+ protected:
+
+ bool m_onlyFixed;
+ QString m_sampleText, m_title;
+ QLabel *m_sampleLabel;
+ QPushButton *m_button;
+ QFont m_selFont;
+
+};
+
+
+KFontRequester::KFontRequester( QWidget *parent, const char *name,
+ bool onlyFixed ) : QWidget( parent, name ),
+ m_onlyFixed( onlyFixed )
+{
+ QHBoxLayout *layout = new QHBoxLayout( this, 0, KDialog::spacingHint() );
+
+ m_sampleLabel = new QLabel( this, "m_sampleLabel" );
+ m_button = new QPushButton( i18n( "Choose..." ), this, "m_button" );
+
+ m_sampleLabel->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
+ setFocusProxy( m_button );
+
+ layout->addWidget( m_sampleLabel, 1 );
+ layout->addWidget( m_button );
+
+ connect( m_button, SIGNAL( clicked() ), SLOT( buttonClicked() ) );
+
+ displaySampleText();
+
+}
+
+void KFontRequester::setFont( const QFont &font, bool onlyFixed )
+{
+ m_selFont = font;
+ m_onlyFixed = onlyFixed;
+
+ displaySampleText();
+}
+void KFontRequester::buttonClicked()
+{
+ int result = KFontDialog::getFont( m_selFont, m_onlyFixed, parentWidget() );
+
+ if ( result == KDialog::Accepted )
+ {
+ displaySampleText();
+ }
+}
+
+void KFontRequester::displaySampleText()
+{
+ m_sampleLabel->setFont( m_selFont );
+
+ int size = m_selFont.pointSize();
+ if(size == -1)
+ size = m_selFont.pixelSize();
+
+ if ( m_sampleText.isEmpty() )
+ m_sampleLabel->setText( QString( "%1 %2" ).arg( m_selFont.family() )
+ .arg( size ) );
+ else
+ m_sampleLabel->setText( m_sampleText );
+}
+#endif
+
+QalculatePreferencesDialog::QalculatePreferencesDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Preferences"), Ok | Apply | Cancel, Ok, false) {
+
+#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
+ QTabWidget *tabs = new QTabWidget(this);
+#else
+ QTabWidget *tabs = new KTabWidget(this);
+#endif
+ setMainWidget(tabs);
+ QWidget *page1 = new QWidget(this);
+ QWidget *page2 = new QWidget(this);
+ tabs->addTab(page1, i18n("General"));
+ tabs->addTab(page2, i18n("Fonts"));
+
+ QVBoxLayout *vbox = new QVBoxLayout(page1, spacingHint());
+ systrayButton = new QCheckBox(i18n("Close to system tray"), page1);
+ QToolTip::add(systrayButton, i18n("If the application will reside in the system tray when the window is closed"));
+ vbox->addWidget(systrayButton);
+ statusButton = new QCheckBox(i18n("Display expression status"), page1);
+ QToolTip::add(statusButton, i18n("If as-you-type expression status shall be displayed below the expression entry"));
+ vbox->addWidget(statusButton);
+ iconsButton = new QCheckBox(i18n("Use icon buttons"), page1);
+ QToolTip::add(iconsButton, i18n("Use icons instead of text on the top-right buttons. The third state uses the style setting for icons on buttons."));
+ iconsButton->setTristate(true);
+ vbox->addWidget(iconsButton);
+ fetchExchangeRatesButton = new QCheckBox(i18n("Update exchange rates on start"), page1);
+ QToolTip::add(fetchExchangeRatesButton, i18n("If current exchange rates shall be downloaded from the internet at program start"));
+ vbox->addWidget(fetchExchangeRatesButton);
+ saveModeButton = new QCheckBox(i18n("Save mode on exit"), page1);
+ QToolTip::add(saveModeButton, i18n("If the mode of the calculator shall be restored"));
+ vbox->addWidget(saveModeButton);
+ saveDefsButton = new QCheckBox(i18n("Save definitions on exit"), page1);
+ QToolTip::add(saveDefsButton, i18n("If changes to functions, units and variables shall be saved automatically"));
+ vbox->addWidget(saveDefsButton);
+ rpnKeypadOnlyButton = new QCheckBox(i18n("Use only keypad keys for RPN"), page1);
+ QToolTip::add(rpnKeypadOnlyButton, i18n("Use only keypad keys for RPN operations (+-*/^) and use the rest of the keyboard for expression entry"));
+ vbox->addWidget(rpnKeypadOnlyButton);
+ dotAsSeparatorButton = new QCheckBox(i18n("Ignores dots in numbers"), page1);
+ QToolTip::add(dotAsSeparatorButton, i18n("Allow dots, '.', to be used as thousands separator instead of as an alternative to decimal sign"));
+ if(CALCULATOR->getDecimalPoint() == ".") dotAsSeparatorButton->hide();
+ vbox->addWidget(dotAsSeparatorButton);
+ unicodeButton = new QCheckBox(i18n("Enable unicode signs"), page1);
+ QToolTip::add(unicodeButton, i18n("Disable this if you have problems with some fancy characters"));
+ vbox->addWidget(unicodeButton);
+ lowerCaseButton = new QCheckBox(i18n("Use lower case in numbers"), page1);
+ QToolTip::add(lowerCaseButton, i18n("If lower case letters should be used in numbers with non-decimal base"));
+ vbox->addWidget(lowerCaseButton);
+ lowerCaseEButton = new QCheckBox(i18n("Use lower case \"e\""), page1);
+ QToolTip::add(lowerCaseEButton, i18n("If \"e\"; shall be used instead of \"E\" in numbers"));
+ vbox->addWidget(lowerCaseEButton);
+ alternativeBasePrefixButton = new QCheckBox(i18n("Alternative base prefixes"), page1);
+ QToolTip::add(alternativeBasePrefixButton, i18n("If hexadecimal numbers shall be displayed with \"0x0\" and binary numbers with \"0b00\" as prefixes"));
+ vbox->addWidget(alternativeBasePrefixButton);
+ spellOutLogicalOperatorsButton = new QCheckBox(i18n("Spell out logical operators"), page1);
+ QToolTip::add(spellOutLogicalOperatorsButton, i18n("If logical and/or shall be displayed as \"&&\"/\"||\" or \"and\"/\"or\""));
+ vbox->addWidget(spellOutLogicalOperatorsButton);
+ QGridLayout *grid = new QGridLayout(vbox);
+ multiplicationLabel = new QLabel(i18n("Multiplication sign:"), page1);
+ grid->addWidget(multiplicationLabel, 0, 0);
+ QButtonGroup *group = new QButtonGroup();
+ dotButton = new QRadioButton(SIGN_MULTIDOT, page1);
+ group->insert(dotButton, 0);
+ grid->addWidget(dotButton, 0, 1);
+ exButton = new QRadioButton(SIGN_MULTIPLICATION, page1);
+ group->insert(exButton, 1);
+ grid->addWidget(exButton, 0, 2);
+ asteriskButton = new QRadioButton("*", page1);
+ group->insert(asteriskButton, 2);
+ grid->addWidget(asteriskButton, 0, 3);
+ divisionLabel = new QLabel(i18n("Division sign:"), page1);
+ grid->addWidget(divisionLabel, 1, 0);
+ group = new QButtonGroup();
+ divisionSlashButton = new QRadioButton(" " SIGN_DIVISION_SLASH " ", page1);
+ group->insert(divisionSlashButton, 0);
+ grid->addWidget(divisionSlashButton, 1, 1);
+ divisionButton = new QRadioButton(SIGN_DIVISION, page1);
+ group->insert(divisionButton, 1);
+ grid->addWidget(divisionButton, 1, 2);
+ slashButton = new QRadioButton("/", page1);
+ group->insert(slashButton, 2);
+ grid->addWidget(slashButton, 1, 3);
+ vbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
+
+ vbox = new QVBoxLayout(page2, spacingHint());
+ useCustomResultFontButton = new QCheckBox(i18n("Custom result font"), page2);
+ vbox->addWidget(useCustomResultFontButton);
+ resultFontEdit = new KFontRequester(page2);
+ vbox->addWidget(resultFontEdit);
+ useCustomExpressionFontButton = new QCheckBox(i18n("Custom expression font"), page2);
+ vbox->addWidget(useCustomExpressionFontButton);
+ expressionFontEdit = new KFontRequester(page2);
+ vbox->addWidget(expressionFontEdit);
+ useCustomStatusFontButton = new QCheckBox(i18n("Custom status font"), page2);
+ vbox->addWidget(useCustomStatusFontButton);
+ statusFontEdit = new KFontRequester(page2);
+ vbox->addWidget(statusFontEdit);
+ grid = new QGridLayout(vbox);
+ grid->addWidget(new QLabel(i18n("Status error color:"), page2), 0, 0);
+#if KDE_VERSION_MAJOR == 3 && KDE_VERSION_MINOR < 1
+ statusErrorColorButton = new KColorButton(page2);
+#else
+ statusErrorColorButton = new KColorButton("red", "red", page2);
+#endif
+ grid->addWidget(statusErrorColorButton, 0, 1);
+ grid->addWidget(new QLabel(i18n("Status warning color:"), page2), 1, 0);
+#if KDE_VERSION_MAJOR == 3 && KDE_VERSION_MINOR < 1
+ statusWarningColorButton = new KColorButton(page2);
+#else
+ statusWarningColorButton = new KColorButton("blue", "blue", page2);
+#endif
+ grid->addWidget(statusWarningColorButton, 1, 1);
+ vbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
+
+
+ connect(useCustomResultFontButton, SIGNAL(toggled(bool)), resultFontEdit, SLOT(setEnabled(bool)));
+ connect(useCustomExpressionFontButton, SIGNAL(toggled(bool)), expressionFontEdit, SLOT(setEnabled(bool)));
+ connect(useCustomStatusFontButton, SIGNAL(toggled(bool)), statusFontEdit, SLOT(setEnabled(bool)));
+ connect(unicodeButton, SIGNAL(toggled(bool)), multiplicationLabel, SLOT(setEnabled(bool)));
+ connect(unicodeButton, SIGNAL(toggled(bool)), dotButton, SLOT(setEnabled(bool)));
+ connect(unicodeButton, SIGNAL(toggled(bool)), exButton, SLOT(setEnabled(bool)));
+ connect(unicodeButton, SIGNAL(toggled(bool)), asteriskButton, SLOT(setEnabled(bool)));
+ connect(unicodeButton, SIGNAL(toggled(bool)), divisionLabel, SLOT(setEnabled(bool)));
+ connect(unicodeButton, SIGNAL(toggled(bool)), divisionSlashButton, SLOT(setEnabled(bool)));
+ connect(unicodeButton, SIGNAL(toggled(bool)), divisionButton, SLOT(setEnabled(bool)));
+ connect(unicodeButton, SIGNAL(toggled(bool)), slashButton, SLOT(setEnabled(bool)));
+
+}
+
+QalculatePreferencesDialog::~QalculatePreferencesDialog() {}
+
+void QalculatePreferencesDialog::slotApply() {
+ rpn_keypad_only = rpnKeypadOnlyButton->isChecked();
+ evalops.parse_options.dot_as_separator = dotAsSeparatorButton->isChecked();
+ close_to_systray = systrayButton->isChecked();
+ display_expression_status = statusButton->isChecked();
+ switch(iconsButton->state()) {
+ case QButton::Off: {
+ use_icon_buttons = 0;
+ break;
+ }
+ case QButton::On: {
+ use_icon_buttons = 1;
+ break;
+ }
+ case QButton::NoChange: {
+ use_icon_buttons = -1;
+ break;
+ }
+ }
+ fetch_exchange_rates_at_startup = fetchExchangeRatesButton->isChecked();
+ save_mode_on_exit = saveModeButton->isChecked();
+ printops.use_unicode_signs = unicodeButton->isChecked();
+ printops.lower_case_numbers = lowerCaseButton->isChecked();
+ printops.lower_case_e = lowerCaseEButton->isChecked();
+ if(alternativeBasePrefixButton->isChecked()) printops.base_display = BASE_DISPLAY_ALTERNATIVE;
+ else printops.base_display = BASE_DISPLAY_NORMAL;
+ printops.spell_out_logical_operators = spellOutLogicalOperatorsButton->isChecked();
+ save_defs_on_exit = saveDefsButton->isChecked();
+ use_custom_result_font = useCustomResultFontButton->isChecked();
+ use_custom_expression_font = useCustomExpressionFontButton->isChecked();
+ use_custom_status_font = useCustomStatusFontButton->isChecked();
+ custom_result_font = resultFontEdit->font().toString();
+ custom_expression_font = expressionFontEdit->font().toString();
+ custom_status_font = statusFontEdit->font().toString();
+ status_error_color = statusErrorColorButton->color();
+ if(!status_error_color.isValid()) status_error_color.setNamedColor("red");
+ status_warning_color = statusWarningColorButton->color();
+ if(!status_warning_color.isValid()) status_warning_color.setNamedColor("blue");
+ if(dotButton->isChecked()) {
+ printops.multiplication_sign = MULTIPLICATION_SIGN_DOT;
+ } else if(exButton->isChecked()) {
+ printops.multiplication_sign = MULTIPLICATION_SIGN_X;
+ } else {
+ printops.multiplication_sign = MULTIPLICATION_SIGN_ASTERISK;
+ }
+ if(divisionSlashButton->isChecked()) {
+ printops.division_sign = DIVISION_SIGN_DIVISION_SLASH;
+ } else if(divisionButton->isChecked()) {
+ printops.division_sign = DIVISION_SIGN_DIVISION;
+ } else {
+ printops.division_sign = DIVISION_SIGN_SLASH;
+ }
+ mainWin->applyPreferences();
+}
+bool QalculatePreferencesDialog::editPreferences() {
+
+ rpnKeypadOnlyButton->setChecked(rpn_keypad_only);
+ dotAsSeparatorButton->setChecked(evalops.parse_options.dot_as_separator);
+ systrayButton->setChecked(close_to_systray);
+ statusButton->setChecked(display_expression_status);
+ if(use_icon_buttons < 0) {
+ iconsButton->setNoChange();
+ } else {
+ iconsButton->setChecked(use_icon_buttons > 0);
+ }
+ fetchExchangeRatesButton->setChecked(fetch_exchange_rates_at_startup);
+ saveModeButton->setChecked(save_mode_on_exit);
+ unicodeButton->setChecked(printops.use_unicode_signs);
+ lowerCaseButton->setChecked(printops.lower_case_numbers);
+ lowerCaseEButton->setChecked(printops.lower_case_e);
+ alternativeBasePrefixButton->setChecked(printops.base_display == BASE_DISPLAY_ALTERNATIVE);
+ spellOutLogicalOperatorsButton->setChecked(printops.spell_out_logical_operators);
+ saveDefsButton->setChecked(save_defs_on_exit);
+ useCustomResultFontButton->setChecked(use_custom_result_font);
+ useCustomExpressionFontButton->setChecked(use_custom_expression_font);
+ useCustomStatusFontButton->setChecked(use_custom_status_font);
+ QFont font1(resultWidget->font());
+ font1.fromString(custom_result_font);
+ resultFontEdit->setFont(font1);
+ resultFontEdit->setEnabled(use_custom_result_font);
+ QFont font2(expressionWidget->font());
+ font2.fromString(custom_expression_font);
+ expressionFontEdit->setFont(font2);
+ expressionFontEdit->setEnabled(use_custom_expression_font);
+ QFont font3(statusWidget_l->font());
+ font3.fromString(custom_status_font);
+ statusFontEdit->setFont(font3);
+ statusFontEdit->setEnabled(use_custom_status_font);
+ statusErrorColorButton->setColor(status_error_color);
+ statusWarningColorButton->setColor(status_warning_color);
+ if(can_display_unicode_string_function(SIGN_MULTIDOT, (void*) dotButton)) dotButton->setText(SIGN_MULTIDOT);
+ else dotButton->setText(SIGN_SMALLCIRCLE);
+ switch(printops.multiplication_sign) {
+ case MULTIPLICATION_SIGN_DOT: {
+ dotButton->setChecked(true);
+ break;
+ }
+ case MULTIPLICATION_SIGN_X: {
+ exButton->setChecked(true);
+ break;
+ }
+ default: {
+ asteriskButton->setChecked(true);
+ break;
+ }
+ }
+ asteriskButton->setEnabled(printops.use_unicode_signs);
+ exButton->setEnabled(printops.use_unicode_signs);
+ dotButton->setEnabled(printops.use_unicode_signs);
+ multiplicationLabel->setEnabled(printops.use_unicode_signs);
+ switch(printops.division_sign) {
+ case DIVISION_SIGN_DIVISION_SLASH: {
+ divisionSlashButton->setChecked(true);
+ break;
+ }
+ case DIVISION_SIGN_DIVISION: {
+ divisionButton->setChecked(true);
+ break;
+ }
+ default: {
+ slashButton->setChecked(true);
+ break;
+ }
+ }
+ slashButton->setEnabled(printops.use_unicode_signs);
+ divisionSlashButton->setEnabled(printops.use_unicode_signs);
+ divisionButton->setEnabled(printops.use_unicode_signs);
+ divisionLabel->setEnabled(printops.use_unicode_signs);
+
+ if(exec() == Accepted) {
+ slotApply();
+ return true;
+ }
+ return false;
+
+}
+
+
+#include "qalculatepreferencesdialog.moc"
diff --git a/src/qalculatepreferencesdialog.h b/src/qalculatepreferencesdialog.h
new file mode 100644
index 0000000..feb42d3
--- /dev/null
+++ b/src/qalculatepreferencesdialog.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * Copyright (C) 2005-2006 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEPREFERENCESDIALOG_H
+#define QALCULATEPREFERENCESDIALOG_H
+
+#include <kdialogbase.h>
+
+class QCheckBox;
+class QRadioButton;
+class QLabel;
+class KFontRequester;
+class KColorButton;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculatePreferencesDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculatePreferencesDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculatePreferencesDialog();
+
+ bool editPreferences();
+
+ QCheckBox *rpnKeypadOnlyButton, *systrayButton, *statusButton, *iconsButton, *fetchExchangeRatesButton, *saveModeButton, *saveDefsButton, *dotAsSeparatorButton, *unicodeButton, *lowerCaseButton, *lowerCaseEButton, *alternativeBasePrefixButton, *spellOutLogicalOperatorsButton, *useCustomResultFontButton, *useCustomExpressionFontButton, *useCustomStatusFontButton;
+ QRadioButton *dotButton, *exButton, *asteriskButton, *divisionSlashButton, *divisionButton, *slashButton;
+ QLabel *multiplicationLabel, *divisionLabel;
+ KFontRequester *resultFontEdit, *expressionFontEdit, *statusFontEdit;
+ KColorButton *statusErrorColorButton, *statusWarningColorButton;
+
+protected slots:
+
+ void slotApply();
+
+};
+
+#endif
diff --git a/src/qalculateresultdisplay.cpp b/src/qalculateresultdisplay.cpp
new file mode 100644
index 0000000..91f5667
--- /dev/null
+++ b/src/qalculateresultdisplay.cpp
@@ -0,0 +1,495 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateresultdisplay.h"
+
+#include "qalculate_kde_utils.h"
+#include "kqalculate.h"
+#include <kpopupmenu.h>
+#include <kxmlguifactory.h>
+#include <kxmlguiclient.h>
+#include <kaction.h>
+#include <kmessagebox.h>
+#include <qwhatsthis.h>
+#include <qtooltip.h>
+#include <klocale.h>
+#include <kapplication.h>
+#include <qsimplerichtext.h>
+
+extern vector<mode_struct> modes;
+
+extern QString parsed_text;
+extern KQalculate *mainWin;
+extern MathStructure *mstruct;
+extern PrintOptions printops;
+extern EvaluationOptions evalops;
+
+QString linkInfo(const MathStructure *m, QWidget *w, bool full_length = false) {
+ QString str;
+ if(m) {
+ if(m->isSymbolic()) {
+ str = "\"";
+ str += m->symbol().c_str();
+ str += "\"";
+ } else if(m->isVector()) {
+ if(m->isMatrix()) {
+ str = i18n("a matrix");
+ } else {
+ str = i18n("a vector");
+ }
+ str += "\n";
+ str += i18n("double-click to view/edit");
+ } else if(m->isVariable()) {
+ if(m->variable()->subtype() == SUBTYPE_UNKNOWN_VARIABLE) {
+ str = i18n("Unknown variable");
+ } else {
+ str = i18n("Variable");
+ }
+ str += ": ";
+ str += m->variable()->title(true).c_str();
+ } else if(m->isUnit()) {
+ str = i18n("Unit");
+ str += ": ";
+ str += m->unit()->title(true).c_str();
+ if(m->prefix() && m->prefix() != CALCULATOR->decimal_null_prefix && m->prefix() != CALCULATOR->binary_null_prefix) {
+ str += "\n";
+ str += i18n("Prefix");
+ str += ": ";
+ QString pstr;
+ switch(m->prefix()->type()) {
+ case PREFIX_DECIMAL: {
+ QTextOStream(&pstr) << m->prefix()->name(false, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) w).c_str() << " (10e" << ((DecimalPrefix*) m->prefix())->exponent() << ")";
+ break;
+ }
+ case PREFIX_BINARY: {
+ QTextOStream(&pstr) << m->prefix()->name(false, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) w).c_str() << " (2e" << ((BinaryPrefix*) m->prefix())->exponent() << ")";
+ break;
+ }
+ case PREFIX_NUMBER: {
+ QTextOStream(&pstr) << m->prefix()->name(false, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) w).c_str();
+ break;
+ }
+ }
+ str += pstr;
+ }
+ } else if(m->isFunction()) {
+ str = i18n("Function");
+ str += ": ";
+ str += m->function()->title(true).c_str();
+ Argument default_arg;
+ MathFunction *f = m->function();
+ str += "<br>";
+ const ExpressionName *ename = &f->preferredName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) w);
+ str += "<i><b>";
+ str += ename->name.c_str();
+ str += "</b>";
+ int iargs = f->maxargs();
+ if(iargs < 0) {
+ iargs = f->minargs() + 1;
+ }
+ str += "(";
+ if(iargs != 0) {
+ for(int i2 = 1; i2 <= iargs; i2++) {
+ if(i2 > f->minargs()) {
+ str += "[";
+ }
+ if(i2 > 1) {
+ str += CALCULATOR->getComma().c_str();
+ str += " ";
+ }
+ Argument *arg = f->getArgumentDefinition(i2);
+ if(arg && !arg->name().empty()) {
+ str += arg->name().c_str();
+ } else {
+ str += i18n("argument");
+ str += " ";
+ str += QString::number(i2);
+ }
+ if(i2 > f->minargs()) {
+ str += "]";
+ }
+ }
+ if(f->maxargs() < 0) {
+ str += CALCULATOR->getComma().c_str();
+ str += " ...";
+ }
+ }
+ str += ")";
+ str += "</i>";
+ if(full_length) {
+ str += "<i>";
+ for(size_t i2 = 1; i2 <= f->countNames(); i2++) {
+ if(&f->getName(i2) != ename) {
+ str += "<br>";
+ str += f->getName(i2).name.c_str();
+ }
+ }
+ str += "</i>";
+ if(f->subtype() == SUBTYPE_DATA_SET) {
+ str += "<br>";
+ str += "<br>";
+ QString str2;
+ str2.sprintf(i18n("Retrieves data from the %s data set for a given object and property. If \"info\" is typed as property, a dialog window will pop up with all properties of the object."), f->title().c_str());
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ }
+ if(!f->description().empty()) {
+ str += "<br>";
+ str += "<br>";
+ QString str2 = f->description().c_str();
+ str2.replace("<", "&lt;");
+ str2.replace(">", "&gt;");
+ str += str2;
+ }
+ }
+ }
+ }
+ return str;
+}
+
+
+QString linkInfo(const QString &link, QWidget *w, bool full_length = false) {
+ if(!link.isEmpty() && link[0] == '+') {
+ QString str = link;
+ str.remove(0, 1);
+ return str;
+ } else {
+ return linkInfo(mainWin->getResultPart(link.toInt()), w, full_length);
+ }
+}
+
+class QalculateExpressionToolTip : public QToolTip {
+
+public:
+
+ QalculateResultDisplay *qrd;
+
+ QalculateExpressionToolTip(QalculateResultDisplay *parent, QToolTipGroup *group = 0) : QToolTip(parent->viewport(), group) {
+ qrd = parent;
+ }
+ virtual ~QalculateExpressionToolTip() {}
+
+protected:
+
+ void maybeTip(const QPoint &p) {
+ int cx = qrd->contentsX();
+ int cy = qrd->contentsY();
+ QString str = qrd->anchorAt(qrd->viewportToContents(p), Qt::AnchorName);
+ if(str.isEmpty()) return;
+ int w = 5;
+ while(p.x() + w < qrd->visibleWidth() && qrd->anchorAt(QPoint(p.x() + cx + w, p.y() + cy), Qt::AnchorName) == str) {
+ w += 5;
+ }
+ int x = p.x() - 5;
+ w += 5;
+ while(x > 0 && qrd->anchorAt(QPoint(x + cx, p.y() + cy), Qt::AnchorName) == str) {
+ x -= 5;
+ w += 5;
+ }
+ if(x < 0) x = 0;
+ if(w + x > qrd->visibleWidth()) w = qrd->visibleWidth() - x;
+ int h = 5;
+ while(p.y() + h < qrd->visibleHeight() && qrd->anchorAt(QPoint(p.x() + cx, p.y() + cy + h), Qt::AnchorName) == str) {
+ h += 5;
+ }
+ int y = p.y() - 5;
+ h += 5;
+ while(y > 0 && qrd->anchorAt(QPoint(p.x() + cx, y + cy), Qt::AnchorName) == str) {
+ y -= 5;
+ h += 5;
+ }
+ if(y < 0) y = 0;
+ if(h + y > qrd->visibleHeight()) h = qrd->visibleHeight() - y;
+ tip(QRect(x, y, w, h), linkInfo(str, qrd, true));
+ }
+
+};
+
+QalculateResultDisplay::QalculateResultDisplay(QWidget *parent, const char *name): QTextBrowser(parent, name) {
+
+ setResizePolicy(AutoOneFit);
+ setVScrollBarMode(Auto);
+ setHScrollBarMode(Auto);
+ setTextFormat(Qt::RichText);
+ setFrameStyle(QFrame::NoFrame);
+ //setFocusPolicy(QWidget::TabFocus);
+ paletteChanged();
+ m_under_pointer = NULL;
+
+ QToolTipGroup *tgroup = new QToolTipGroup(viewport());
+ tooltip = new QalculateExpressionToolTip(this, tgroup);
+
+ //connect(this, SIGNAL(anchorClicked(const QString&, const QString&)), this, SLOT(onAnchorClicked(const QString&, const QString&)));
+ connect(this, SIGNAL(doubleClicked(int, int)), this, SLOT(onDoubleClicked(int, int)));
+ if(kapp) {
+ connect(kapp, SIGNAL(kdisplayPaletteChanged()), this, SLOT(paletteChanged()));
+ }
+
+}
+
+QalculateResultDisplay::~QalculateResultDisplay() {}
+
+void QalculateResultDisplay::setRightMargin(int i_margin) {
+ setMargins(0, 0, i_margin, 0);
+}
+
+void QalculateResultDisplay::onAnchorClicked(const QString&, const QString&) {
+ /*if(name.isEmpty()) return;
+ QWhatsThis::display(linkInfo(name, this, true));*/
+}
+
+QPopupMenu *QalculateResultDisplay::createPopupMenu(const QPoint &pos) {
+
+ m_under_pointer = NULL;
+
+ QPopupMenu *menu = QTextBrowser::createPopupMenu(pos);
+ menu->insertSeparator();
+ mainWin->ActionStoreResult->plug(menu);
+ mainWin->ActionSaveAsImage->plug(menu);
+ menu->insertSeparator();
+ if(mstruct && mstruct->containsType(STRUCT_ADDITION)) {
+ if(evalops.structuring != STRUCTURING_FACTORIZE) {
+ mainWin->ActionFactorize->plug(menu);
+ }
+ if(evalops.structuring != STRUCTURING_SIMPLIFY) {
+ mainWin->ActionSimplify->plug(menu);
+ }
+ } else if(mstruct && mstruct->isNumber() && mstruct->number().isInteger() && !mstruct->number().isZero()) {
+ mainWin->ActionFactorize->plug(menu);
+ menu->insertSeparator();
+ }
+ if(mstruct && mstruct->containsUnknowns()) {
+ mainWin->ActionSetUnknowns->plug(menu);
+ }
+ if(mstruct && (mstruct->containsType(STRUCT_ADDITION) || mstruct->containsUnknowns())) {
+ menu->insertSeparator();
+ }
+ if(mstruct && mstruct->containsDivision()) {
+ mainWin->ActionNonZeroDenominators->plug(menu);
+ menu->insertSeparator();
+ }
+ int id = menu->insertItem(i18n("Normal"));
+ if(printops.min_exp == EXP_PRECISION) menu->setItemChecked(id, true);
+ else menu->connectItem(id, this, SLOT(displayNormal()));
+ id = menu->insertItem(i18n("Engineering"));
+ if(printops.min_exp == EXP_BASE_3) menu->setItemChecked(id, true);
+ else menu->connectItem(id, this, SLOT(displayEngineering()));
+ id = menu->insertItem(i18n("Scientific"));
+ if(printops.min_exp == EXP_SCIENTIFIC) menu->setItemChecked(id, true);
+ else menu->connectItem(id, this, SLOT(displayScientific()));
+ /*mainWin->ActionNumericalDisplayNormal->plug(menu);
+ mainWin->ActionNumericalDisplayEngineering->plug(menu);
+ mainWin->ActionNumericalDisplayScientific->plug(menu);*/
+ if(!mstruct || !mstruct->containsType(STRUCT_UNIT)) {
+ menu->insertSeparator();
+ mainWin->ActionNumberBaseBinary->plug(menu);
+ mainWin->ActionNumberBaseOctal->plug(menu);
+ mainWin->ActionNumberBaseDecimal->plug(menu);
+ mainWin->ActionNumberBaseHexadecimal->plug(menu);
+ menu->insertSeparator();
+ mainWin->ActionFractionalDisplayDecimal->plug(menu);
+ mainWin->ActionFractionalDisplayDecimalTryExact->plug(menu);
+ mainWin->ActionFractionalDisplayFraction->plug(menu);
+ mainWin->ActionFractionalDisplayCombined->plug(menu);
+ }
+ menu->insertSeparator();
+ mainWin->ActionAbbreviateNames->plug(menu);
+ if(mstruct && mstruct->containsType(STRUCT_UNIT)) {
+ menu->insertSeparator();
+ mainWin->ActionConvertToUnitExpression->plug(menu);
+ mainWin->ActionConvertToBaseUnits->plug(menu);
+ mainWin->ActionConvertToBestUnit->plug(menu);
+ menu->insertSeparator();
+ mainWin->ActionEnablePrefixes->plug(menu);
+ mainWin->ActionEnableUseOfAllPrefixes->plug(menu);
+ mainWin->ActionEnableDenominatorPrefixes->plug(menu);
+ }
+ menu->insertSeparator();
+ QPopupMenu *modes_menu = new QPopupMenu(menu);
+ QObject::connect(modes_menu, SIGNAL(activated(int)), mainWin, SLOT(loadMode(int)));
+ for(size_t i = 0; i < modes.size(); i++) {
+ modes_menu->insertItem(modes[i].name, i, i);
+ }
+ modes_menu->insertSeparator();
+ mainWin->ActionSaveModeAs->plug(modes_menu);
+ mainWin->ActionDeleteMode->plug(modes_menu);
+ menu->insertItem(i18n("Meta Modes"), modes_menu);
+ if(parsed_text.isEmpty()) return menu;
+ menu->insertSeparator();
+ menu->insertItem(i18n("Show Parsed Expression"), this, SLOT(showParsedExpression()));
+ QString str = anchorAt(pos, Qt::AnchorName);
+ if(!str.isEmpty()) {
+ if(str[0] == '+') {
+ name_under_pointer = str;
+ name_under_pointer.remove(0, 1);
+ menu->insertItem(i18n("Show Object Info"), this, SLOT(showInfo()));
+ } else {
+ m_under_pointer = mainWin->getResultPart(str.toInt());
+ if(m_under_pointer) {
+ if(m_under_pointer->isVector()) {
+ if(m_under_pointer->isMatrix()) {
+ menu->insertItem(i18n("View/Edit Matrix"), this, SLOT(editMatrix()));
+ } else {
+ menu->insertItem(i18n("View/Edit Vector"), this, SLOT(editVector()));
+ }
+ } else {
+ menu->insertItem(i18n("Show Object Info"), this, SLOT(showInfo()));
+ }
+ }
+ }
+ }
+ curpos = viewport()->mapToGlobal(pos);
+ return menu;
+
+}
+
+void QalculateResultDisplay::displayNormal() {
+ printops.negative_exponents = false;
+ printops.sort_options.minus_last = true;
+ mainWin->ActionNumericalDisplayNormal->activate();
+ mainWin->ActionNegativeExponents->setChecked(false);
+ mainWin->ActionSortMinusLast->setChecked(true);
+}
+void QalculateResultDisplay::displayEngineering() {
+ mainWin->ActionNumericalDisplayEngineering->activate();
+}
+void QalculateResultDisplay::displayScientific() {
+ printops.negative_exponents = true;
+ printops.sort_options.minus_last = false;
+ mainWin->ActionNumericalDisplayScientific->activate();
+ mainWin->ActionNegativeExponents->setChecked(true);
+ mainWin->ActionSortMinusLast->setChecked(false);
+}
+
+void QalculateResultDisplay::showParsedExpression() {
+ QString str = i18n("Parsed expression:");
+ str += "\n";
+ str += parsed_text;
+ QWhatsThis::display(str, curpos);
+}
+void QalculateResultDisplay::showInfo() {
+ if(m_under_pointer) {
+ QWhatsThis::display(linkInfo(m_under_pointer, this, true), curpos);
+ } else {
+ QWhatsThis::display(linkInfo(name_under_pointer, this, true), curpos);
+ }
+}
+void QalculateResultDisplay::editVector() {
+ mainWin->insertMatrixVector(m_under_pointer, true, false, true);
+}
+void QalculateResultDisplay::editMatrix() {
+ mainWin->insertMatrixVector(m_under_pointer, false, false, true);
+}
+
+void QalculateResultDisplay::paletteChanged() {
+ QPalette p = kapp ? kapp->palette() : palette();
+ p.setBrush(QColorGroup::Base, p.brush(QPalette::Normal, QColorGroup::Background));
+ p.setColor(QColorGroup::Text, p.color(QPalette::Normal, QColorGroup::Foreground));
+ setPalette(p);
+}
+
+void QalculateResultDisplay::virtual_hook(int, void*) {
+}
+
+void QalculateResultDisplay::focusInEvent(QFocusEvent* fe) {
+ QTextBrowser::focusInEvent(fe);
+ if(fe->reason() == QFocusEvent::Tab || fe->reason() == QFocusEvent::Backtab)
+ selectAll(true);
+}
+
+void QalculateResultDisplay::focusOutEvent(QFocusEvent* fe) {
+ QTextBrowser::focusOutEvent(fe);
+ if(fe->reason() == QFocusEvent::Tab || fe->reason() == QFocusEvent::Backtab)
+ selectAll(false);
+}
+
+void QalculateResultDisplay::onDoubleClicked(int, int) {
+ curpos = QCursor::pos();
+ QString str = anchorAt(viewportToContents(viewport()->mapFromGlobal(curpos)), Qt::AnchorName);
+ if(!str.isEmpty()) {
+ if(str[0] == '+') {
+ selectAll(false);
+ name_under_pointer = str;
+ name_under_pointer.remove(0, 1);
+ showInfo();
+ } else {
+ m_under_pointer = mainWin->getResultPart(str.toInt());
+ if(m_under_pointer) {
+ selectAll(false);
+ if(m_under_pointer->isVector()) {
+ if(m_under_pointer->isMatrix()) {
+ editMatrix();
+ } else {
+ editVector();
+ }
+ } else {
+ showInfo();
+ }
+ }
+ }
+ }
+}
+
+void QalculateResultDisplay::keyPressEvent(QKeyEvent *e) {
+
+ switch (e->key()) {
+ case Key_Down:
+ case Key_Up:
+ case Key_Left:
+ case Key_Right:
+ // jump over QTextEdit's key navigation breakage.
+ // we're not interested in keyboard navigation within the text
+ QWidget::keyPressEvent(e);
+ break;
+ default:
+ QTextBrowser::keyPressEvent(e);
+ }
+
+}
+
+QSize QalculateResultDisplay::minimumSizeHint() const {
+
+ QSize ms = minimumSize();
+ if((ms.width() > 0) && (ms.height() > 0))
+ return ms;
+
+ int w = 100;
+ if(ms.width() > 0)
+ w = ms.width();
+
+ QSimpleRichText rt("<font size=6>X</font>", font());
+ rt.setWidth(100);
+ QSimpleRichText rt2("<font size=2>X</font>", font());
+ rt2.setWidth(100);
+ int h2 = (int) (rt2.height() / 1.5);
+ h2 += h2 % 2;
+ int h = rt.height() * 2 + h2 + 2 * frameWidth();
+ if(h < ms.height())
+ h = ms.height();
+
+ return QSize(w, h);
+}
+
+QSize QalculateResultDisplay::sizeHint() const {
+ return minimumSizeHint();
+}
+
+
+#include "qalculateresultdisplay.moc"
diff --git a/src/qalculateresultdisplay.h b/src/qalculateresultdisplay.h
new file mode 100644
index 0000000..c5c2af1
--- /dev/null
+++ b/src/qalculateresultdisplay.h
@@ -0,0 +1,79 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATERESULTDISPLAY_H
+#define QALCULATERESULTDISPLAY_H
+
+#include <qtextbrowser.h>
+
+class QPopupMenu;
+class QToolTip;
+class MathStructure;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateResultDisplay : public QTextBrowser {
+
+ Q_OBJECT
+
+public:
+
+ QalculateResultDisplay(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateResultDisplay();
+
+ QPopupMenu *createPopupMenu(const QPoint & pos);
+
+ QToolTip *tooltip;
+ const MathStructure *m_under_pointer;
+ QString name_under_pointer;
+ QPoint curpos;
+
+ QSize minimumSizeHint() const;
+ QSize sizeHint() const;
+
+ void setRightMargin(int);
+
+public slots:
+
+ void onAnchorClicked(const QString&, const QString&);
+ void showParsedExpression();
+
+private slots:
+
+ void paletteChanged();
+ void setSource(const QString &) {}
+ void showInfo();
+ void editVector();
+ void editMatrix();
+ void onDoubleClicked(int, int);
+ void displayEngineering();
+ void displayScientific();
+ void displayNormal();
+
+protected:
+
+ void virtual_hook(int id, void* data);
+ void focusInEvent(QFocusEvent *fe);
+ void focusOutEvent(QFocusEvent *fe);
+ void keyPressEvent(QKeyEvent *e);
+
+};
+
+#endif
diff --git a/src/qalculatesetbasedialog.cpp b/src/qalculatesetbasedialog.cpp
new file mode 100644
index 0000000..b95b205
--- /dev/null
+++ b/src/qalculatesetbasedialog.cpp
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculatesetbasedialog.h"
+
+#include <qradiobutton.h>
+#include <qvbuttongroup.h>
+#include <qspinbox.h>
+#include <klocale.h>
+#include <qvbox.h>
+
+QalculateSetBaseDialog::QalculateSetBaseDialog(QWidget *parent, const char *name)
+ : KDialogBase(parent, name, false, i18n("Number Bases"), Close, Close) {
+
+ QHBox *box = makeHBoxMainWidget();
+
+ radiogroup_output = new QVButtonGroup(i18n("Result Base"), box);
+ radiogroup_output->setRadioButtonExclusive(true);
+ new QRadioButton(i18n("Binary"), radiogroup_output);
+ new QRadioButton(i18n("Octal"), radiogroup_output);
+ new QRadioButton(i18n("Decimal"), radiogroup_output);
+ new QRadioButton(i18n("Hexadecimal"), radiogroup_output);
+ new QRadioButton(i18n("Other:"), radiogroup_output);
+ outputBaseBox = new QSpinBox(2, 36, 1, radiogroup_output);
+ outputBaseBox->setValue(10);
+ new QRadioButton(i18n("Sexagesimal"), radiogroup_output);
+ new QRadioButton(i18n("Time format"), radiogroup_output);
+ new QRadioButton(i18n("Roman numerals"), radiogroup_output);
+
+ radiogroup_input = new QVButtonGroup(i18n("Expression Base"), box);
+ radiogroup_input->setRadioButtonExclusive(true);
+ new QRadioButton(i18n("Binary"), radiogroup_input);
+ new QRadioButton(i18n("Octal"), radiogroup_input);
+ new QRadioButton(i18n("Decimal"), radiogroup_input);
+ new QRadioButton(i18n("Hexadecimal"), radiogroup_input);
+ new QRadioButton(i18n("Other:"), radiogroup_input);
+ inputBaseBox = new QSpinBox(2, 36, 1, radiogroup_input);
+ inputBaseBox->setValue(10);
+ new QRadioButton(i18n("Roman numerals"), radiogroup_input);
+
+}
+
+
+QalculateSetBaseDialog::~QalculateSetBaseDialog() {}
+
+
+#include "qalculatesetbasedialog.moc"
diff --git a/src/qalculatesetbasedialog.h b/src/qalculatesetbasedialog.h
new file mode 100644
index 0000000..21955ba
--- /dev/null
+++ b/src/qalculatesetbasedialog.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATESETBASEDIALOG_H
+#define QALCULATESETBASEDIALOG_H
+
+#include <kdialogbase.h>
+
+class QVButtonGroup;
+class QSpinBox;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateSetBaseDialog : public KDialogBase {
+
+ Q_OBJECT
+
+public:
+
+ QalculateSetBaseDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateSetBaseDialog();
+
+ QVButtonGroup *radiogroup_input, *radiogroup_output;
+ QSpinBox *inputBaseBox, *outputBaseBox;
+
+};
+
+#endif
diff --git a/src/qalculateunitsdialog.cpp b/src/qalculateunitsdialog.cpp
new file mode 100644
index 0000000..1918130
--- /dev/null
+++ b/src/qalculateunitsdialog.cpp
@@ -0,0 +1,560 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculateunitsdialog.h"
+#include "qalculate_kde_utils.h"
+#include "qalculateeditunitdialog.h"
+#include <kpushbutton.h>
+#include <qsplitter.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <klistview.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <qlayout.h>
+#include <kcombobox.h>
+#include <qlabel.h>
+#include <qgroupbox.h>
+#include <klineedit.h>
+#include <kiconloader.h>
+#include <kapplication.h>
+#include <kstdguiitem.h>
+
+extern tree_struct unit_cats;
+extern vector<void*> ia_units;
+extern PrintOptions printops;
+extern EvaluationOptions evalops;
+
+QalculateUnitsDialog::QalculateUnitsDialog(QWidget *parent, const char *name) : KDialog(parent, name, false) {
+
+ unit_edit_dialog = NULL;
+ selected_category = "";
+ selected_unit = NULL;
+ selected_to_unit = NULL;
+ block_unit_convert = true;
+
+ QHBoxLayout *layout = new QHBoxLayout(this, marginHint(), spacingHint());
+
+ setCaption(i18n("Units"));
+
+ QVBoxLayout *leftLayout = new QVBoxLayout(layout, spacingHint());
+
+ QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
+ splitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ leftLayout->addWidget(splitter);
+
+ categoryView = new KListView(splitter);
+ categoryView->addColumn(i18n("Category"));
+ categoryView->setRootIsDecorated(false);
+
+ unitView = new KListView(splitter);
+ unitView->addColumn(i18n("Unit"));
+ unitView->addColumn(i18n("Names"));
+ unitView->addColumn(i18n("Base"));
+ unitView->setRootIsDecorated(false);
+
+ convertGroup = new QGroupBox(3, Qt::Horizontal, i18n("Conversion"), this);
+ convertGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
+ convertGroup->setInsideSpacing(spacingHint());
+ convertGroup->setInsideMargin(spacingHint());
+ convertButton = new KPushButton(QIconSet(SmallIcon("reload")), "", convertGroup);
+ fromEdit = new KLineEdit("1", convertGroup);
+ fromEdit->setAlignment(Qt::AlignRight);
+ fromEdit->setMinimumWidth(100);
+ fromLabel = new QLabel(convertGroup);
+ equalsLabel = new QLabel("=", convertGroup);
+ equalsLabel->setAlignment(Qt::AlignRight);
+ toEdit = new KLineEdit("1", convertGroup);
+ toEdit->setAlignment(Qt::AlignRight);
+ toEdit->setMinimumWidth(100);
+ toCombo = new KComboBox(convertGroup);
+ leftLayout->addWidget(convertGroup);
+
+ QVBoxLayout *buttonLayout = new QVBoxLayout(layout, spacingHint());
+
+ newButton = new QPushButton(i18n("New"), this);
+ buttonLayout->addWidget(newButton);
+ editButton = new QPushButton(i18n("Edit"), this);
+ editButton->setEnabled(false);
+ buttonLayout->addWidget(editButton);
+ deleteButton = new QPushButton(i18n("Delete"), this);
+ deleteButton->setEnabled(false);
+ buttonLayout->addWidget(deleteButton);
+ deactivateButton = new QPushButton(i18n("Deactivate"), this);
+ deactivateButton->setEnabled(false);
+ buttonLayout->addWidget(deactivateButton);
+ insertButton = new QPushButton(i18n("Insert"), this);
+ insertButton->setEnabled(false);
+ buttonLayout->addWidget(insertButton);
+ convertResultButton = new QPushButton(i18n("Convert Result"), this);
+ convertResultButton->setEnabled(false);
+ buttonLayout->addWidget(convertResultButton);
+ buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
+ helpButton = new KPushButton(KStdGuiItem::help(), this);
+ buttonLayout->addWidget(helpButton);
+ buttonClose = new KPushButton(KStdGuiItem::close(), this);
+ buttonLayout->addWidget(buttonClose);
+
+ fromEdit->setFocus();
+
+ resize(QSize(675, 425).expandedTo(size()));
+
+ connect(buttonClose, SIGNAL(clicked()), this, SLOT(close()));
+ connect(newButton, SIGNAL(clicked()), this, SLOT(newUnit()));
+ connect(editButton, SIGNAL(clicked()), this, SLOT(editUnit()));
+ connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteUnit()));
+ connect(deactivateButton, SIGNAL(clicked()), this, SLOT(deactivateUnit()));
+ connect(insertButton, SIGNAL(clicked()), this, SLOT(insertUnit()));
+ connect(convertResultButton, SIGNAL(clicked()), this, SLOT(convertResult()));
+ connect(unitView, SIGNAL(selectionChanged()), this, SLOT(unitSelected()));
+ connect(unitView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(unitDoubleClicked(QListViewItem*)));
+ connect(categoryView, SIGNAL(selectionChanged()), this, SLOT(categorySelected()));
+ connect(toCombo, SIGNAL(activated(int)), this, SLOT(toUnitSelected(int)));
+ connect(convertButton, SIGNAL(clicked()), this, SLOT(convertClicked()));
+ connect(fromEdit, SIGNAL(returnPressed()), this, SLOT(convert()));
+ connect(toEdit, SIGNAL(returnPressed()), this, SLOT(convertReversed()));
+ connect(fromEdit, SIGNAL(lostFocus()), this, SLOT(convert()));
+ connect(toEdit, SIGNAL(lostFocus()), this, SLOT(convertReversed()));
+ connect(helpButton, SIGNAL(clicked()), this, SLOT(slotHelp()));
+
+}
+
+QalculateUnitsDialog::~QalculateUnitsDialog() {
+}
+
+void QalculateUnitsDialog::slotHelp() {
+ KApplication::kApplication()->invokeHelp("qalculate-managers");
+}
+
+void QalculateUnitsDialog::updateUnitTree() {
+ unitItems.clear();
+ comboItems.clear();
+ categoryItems.clear();
+ categoryView->clear();
+ QListViewItem *i = new KListViewItem(categoryView, i18n("All")), *i2;
+ categoryItems[i] = i18n("All");
+ i->setOpen(true);
+ QString str;
+ tree_struct *item, *item2;
+ unit_cats.it = unit_cats.items.begin();
+ if(unit_cats.it != unit_cats.items.end()) {
+ item = &*unit_cats.it;
+ ++unit_cats.it;
+ item->it = item->items.begin();
+ } else {
+ item = NULL;
+ }
+ str = "";
+ i2 = i;
+ while(item) {
+ str += "/";
+ str += item->item.c_str();
+ i = new KListViewItem(i2, item->item.c_str());
+ i->setOpen(false);
+ categoryItems[i] = str;
+ if(str == selected_category) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ while(item && item->it == item->items.end()) {
+ int str_i = str.findRev("/");
+ if(str_i < 0) {
+ str = "";
+ } else {
+ str.truncate(str_i);
+ }
+ item = item->parent;
+ i = i->parent();
+ i2 = i;
+ }
+ if(item) {
+ item2 = &*item->it;
+ if(item->it == item->items.begin())
+ i2 = i;
+ ++item->it;
+ item = item2;
+ item->it = item->items.begin();
+ }
+ }
+ if(!unit_cats.objects.empty()) {
+ //add "Uncategorized" category if there are units without category
+ i = new KListViewItem(categoryView, i18n("Uncategorized"));
+ categoryItems[i] = i18n("Uncategorized");
+ if(selected_category == i18n("Uncategorized")) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ }
+ if(!ia_units.empty()) {
+ //add "Inactive" category if there are inactive units
+ i = new KListViewItem(categoryView, i18n("Inactive"));
+ categoryItems[i] = i18n("Inactive");
+ if(selected_category == i18n("Inactive")) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ }
+ if(!categoryView->selectedItem()) {
+ //if no category has been selected (previously selected has been renamed/deleted), select "All"
+ selected_category = i18n("All");
+ QListViewItemIterator it(categoryView);
+ if(it.current())
+ categoryView->setSelected(it.current(), true);
+ }
+}
+
+#define UPDATE_SELECTED_UNIT QListViewItem *i = unitView->selectedItem(); if(!i) return; selected_unit = unitItems[i]; if(!selected_unit) return;
+#define CHECK_IF_UNIT_STILL_THERE if(!CALCULATOR->stillHasUnit(selected_unit)) {KMessageBox::error(this, i18n("Unit does not exist anymore.")); emit unitsChanged(); return;}
+
+void QalculateUnitsDialog::insertUnit() {
+ UPDATE_SELECTED_UNIT
+ CHECK_IF_UNIT_STILL_THERE
+ emit insertRequest(selected_unit);
+}
+
+void QalculateUnitsDialog::convertResult() {
+ UPDATE_SELECTED_UNIT
+ CHECK_IF_UNIT_STILL_THERE
+ emit convertRequest(selected_unit);
+}
+
+void QalculateUnitsDialog::deactivateUnit() {
+ UPDATE_SELECTED_UNIT
+ CHECK_IF_UNIT_STILL_THERE
+ selected_unit->setActive(!selected_unit->isActive());
+ emit unitsChanged();
+}
+
+void QalculateUnitsDialog::deleteUnit() {
+ UPDATE_SELECTED_UNIT
+ CHECK_IF_UNIT_STILL_THERE
+ if(selected_unit->isLocal()) {
+ if(selected_unit->isUsedByOtherUnits()) {
+ //do not delete units that are used by other units
+ KMessageBox::error(this, i18n("Cannot delete unit as it is needed by other units."));
+ return;
+ }
+ //ensure that all references are removed in Calculator
+ selected_unit->destroy();
+ //update menus and trees
+ emit unitsChanged();
+ }
+}
+
+
+void QalculateUnitsDialog::editUnit() {
+ UPDATE_SELECTED_UNIT
+ CHECK_IF_UNIT_STILL_THERE
+ if(!unit_edit_dialog) {
+ unit_edit_dialog = new QalculateEditUnitDialog(this);
+ }
+ Unit *u = unit_edit_dialog->editUnit(QString::null, selected_unit);
+ if(u) {
+ selected_unit = u;
+ if(!u->isActive()) {
+ selected_category = i18n("Inactive");
+ } else if(u->category().empty()) {
+ selected_category = i18n("Uncategorized");
+ } else {
+ selected_category = "/";
+ selected_category += u->category().c_str();
+ }
+ emit unitsChanged();
+ }
+}
+
+void QalculateUnitsDialog::newUnit() {
+ if(!unit_edit_dialog) {
+ unit_edit_dialog = new QalculateEditUnitDialog(this);
+ }
+ Unit *u = NULL;
+ if(selected_category.isEmpty() || selected_category[0] != '/') {
+ u = unit_edit_dialog->editUnit();
+ } else {
+ QString str = selected_category;
+ str.remove(0, 1);
+ u = unit_edit_dialog->editUnit(str);
+ }
+ if(u) {
+ selected_unit = u;
+ if(!u->isActive()) {
+ selected_category = i18n("Inactive");
+ } else if(u->category().empty()) {
+ selected_category = i18n("Uncategorized");
+ } else {
+ selected_category = "/";
+ selected_category += u->category().c_str();
+ }
+ emit unitsChanged();
+ }
+}
+
+void QalculateUnitsDialog::unitDoubleClicked(QListViewItem*i) {
+ selected_unit = unitItems[i];
+ if(!selected_unit)
+ return;
+ CHECK_IF_UNIT_STILL_THERE
+ if(!unit_edit_dialog) {
+ unit_edit_dialog = new QalculateEditUnitDialog(this);
+ }
+ Unit *u = unit_edit_dialog->editUnit(QString::null, selected_unit);
+ if(u) {
+ selected_unit = u;
+ if(!u->isActive()) {
+ selected_category = i18n("Inactive");
+ } else if(u->category().empty()) {
+ selected_category = i18n("Uncategorized");
+ } else {
+ selected_category = "/";
+ selected_category += u->category().c_str();
+ }
+ emit unitsChanged();
+ }
+}
+
+
+void QalculateUnitsDialog::unitSelected() {
+ QListViewItem *selected = unitView->selectedItem();
+ if(selected) {
+ Unit *u = unitItems[selected];
+ if(!CALCULATOR->stillHasUnit(u)) {
+ KMessageBox::error(this, i18n("Unit does not exist anymore."));
+ selected_unit = NULL;
+ emit unitsChanged();
+ return;
+ }
+ //remember selection
+ selected_unit = u;
+ editButton->setEnabled(true);
+ insertButton->setEnabled(u->isActive());
+ convertResultButton->setEnabled(true);
+ deleteButton->setEnabled(u->isLocal());
+ deactivateButton->setEnabled(true);
+ convertGroup->setEnabled(true);
+ fromLabel->setText(u->print(true, printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) fromLabel).c_str());
+ if(u->isActive())
+ deactivateButton->setText(i18n("Deactivate"));
+ else
+ deactivateButton->setText(i18n("Activate"));
+ } else {
+ editButton->setEnabled(false);
+ insertButton->setEnabled(false);
+ deleteButton->setEnabled(false);
+ deactivateButton->setEnabled(false);
+ convertResultButton->setEnabled(false);
+ convertGroup->setEnabled(false);
+ selected_unit = NULL;
+ }
+ if(!block_unit_convert) convert();
+}
+
+void QalculateUnitsDialog::addUnitTreeItem(Unit *u) {
+ QString snames, sbase;
+ //display name, plural name and short name in the second column
+ AliasUnit *au;
+ for(size_t i = 1; i <= u->countNames(); i++) {
+ if(i > 1) snames += " / ";
+ snames += u->getName(i).name.c_str();
+ }
+ //depending on unit type display relation to base unit(s)
+ switch(u->subtype()) {
+ case SUBTYPE_COMPOSITE_UNIT: {
+ snames = "";
+ sbase = ((CompositeUnit*) u)->print(false, true, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) unitView).c_str();
+ break;
+ }
+ case SUBTYPE_ALIAS_UNIT: {
+ au = (AliasUnit*) u;
+ sbase = au->firstBaseUnit()->preferredDisplayName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) unitView).name.c_str();
+ if(au->firstBaseExponent() != 1) {
+ sbase += POWER;
+ sbase += QString::number(au->firstBaseExponent());
+ }
+ break;
+ }
+ case SUBTYPE_BASE_UNIT: {
+ sbase = "";
+ break;
+ }
+ }
+ QListViewItem *i = new KListViewItem(unitView, u->title(true).c_str(), snames, sbase);
+ unitItems[i] = u;
+ if(u == selected_unit) {
+ unitView->setSelected(i, true);
+ }
+}
+
+
+void QalculateUnitsDialog::categorySelected() {
+ block_unit_convert = true;
+ QListViewItem *selected = categoryView->selectedItem();
+ bool no_cat = false, b_all = false, b_inactive = false;
+ unitView->clear();
+ unitItems.clear();
+ if(!selected) {
+ selected_category = "";
+ unitSelected();
+ return;
+ }
+ selected_category = categoryItems[selected];
+ if(selected_category == i18n("All")) {
+ b_all = true;
+ } else if(selected_category == i18n("Uncategorized")) {
+ no_cat = true;
+ } else if(selected_category == i18n("Inactive")) {
+ b_inactive = true;
+ }
+ if(!b_all && !no_cat && !b_inactive && selected_category[0] == '/') {
+ string str = selected_category.ascii();
+ str.erase(str.begin());
+ for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
+ if(CALCULATOR->units[i]->isActive() && CALCULATOR->units[i]->category().substr(0, selected_category.length() - 1) == str) {
+ addUnitTreeItem(CALCULATOR->units[i]);
+ }
+ }
+ } else {
+ string str = selected_category.ascii();
+ for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
+ if((b_inactive && !CALCULATOR->units[i]->isActive()) || (CALCULATOR->units[i]->isActive() && (b_all || (no_cat && CALCULATOR->units[i]->category().empty()) || (!b_inactive && CALCULATOR->units[i]->category() == str)))) {
+ addUnitTreeItem(CALCULATOR->units[i]);
+ }
+ }
+ }
+ if(!selected_unit || !unitView->selectedItem()) {
+ QListViewItemIterator it(unitView);
+ if(it.current())
+ unitView->setSelected(it.current(), true);
+ }
+ //generate convert to menu
+ toCombo->blockSignals(true);
+ toCombo->clear();
+ comboItems.clear();
+ int i = 0, h = -1;
+ //add all units in units tree to menu
+ QListViewItemIterator it(unitView);
+ Unit *u;
+ while(it.current()) {
+ u = unitItems[it.current()];
+ if(!selected_to_unit) {
+ selected_to_unit = u;
+ }
+ if(u) {
+ toCombo->insertItem(it.current()->text(0));
+ comboItems.push_back(u);
+ if(selected_to_unit == u)
+ h = i;
+ }
+ i++;
+ ++it;
+ }
+
+ //if no items were added to the menu, reset selected unit
+ if(i == 0) {
+ selected_to_unit = NULL;
+ } else {
+ //if no menu item was selected, select the first
+ if(h < 0) {
+ h = 0;
+ QListViewItemIterator it2(unitView);
+ if(it2.current()) {
+ selected_to_unit = unitItems[it2.current()];
+ } else {
+ selected_to_unit = NULL;
+ }
+ }
+ toCombo->setCurrentItem(h);
+ }
+ toCombo->blockSignals(false);
+ block_unit_convert = false;
+ //update conversion display
+ convert();
+}
+
+void QalculateUnitsDialog::toUnitSelected(int index) {
+ if(index < (int) comboItems.size()) {
+ selected_to_unit = comboItems[index];
+ convert();
+ }
+}
+void QalculateUnitsDialog::convertClicked() {
+ if(toEdit->hasFocus()) {
+ convertReversed();
+ } else {
+ convert();
+ }
+}
+void QalculateUnitsDialog::convert() {
+ if(selected_unit && selected_to_unit) {
+ //determine conversion direction
+ bool b = false;
+ if(selected_unit == selected_to_unit) {
+ toEdit->setText(fromEdit->text());
+ } else {
+ EvaluationOptions eo;
+ eo.approximation = APPROXIMATION_APPROXIMATE;
+ eo.parse_options.angle_unit = evalops.parse_options.angle_unit;
+ PrintOptions po;
+ po.is_approximate = &b;
+ po.number_fraction_format = FRACTION_DECIMAL;
+ MathStructure v_mstruct = CALCULATOR->convert(CALCULATOR->unlocalizeExpression(fromEdit->text().ascii(), evalops.parse_options), selected_unit, selected_to_unit, eo);
+ toEdit->setText(v_mstruct.print(po).c_str());
+ b = b || v_mstruct.isApproximate();
+ }
+ if(b && printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) equalsLabel)) {
+ equalsLabel->setText(SIGN_ALMOST_EQUAL);
+ } else {
+ equalsLabel->setText("=");
+ }
+ }
+}
+void QalculateUnitsDialog::convertReversed() {
+ if(selected_unit && selected_to_unit) {
+ bool b = false;
+ if(selected_unit == selected_to_unit) {
+ fromEdit->setText(toEdit->text());
+ } else {
+ EvaluationOptions eo;
+ eo.approximation = APPROXIMATION_APPROXIMATE;
+ eo.parse_options.angle_unit = evalops.parse_options.angle_unit;
+ PrintOptions po;
+ po.is_approximate = &b;
+ po.number_fraction_format = FRACTION_DECIMAL;
+ MathStructure v_mstruct = CALCULATOR->convert(CALCULATOR->unlocalizeExpression(toEdit->text().ascii(), evalops.parse_options), selected_to_unit, selected_unit, eo);
+ fromEdit->setText(v_mstruct.print(po).c_str());
+ b = b || v_mstruct.isApproximate();
+ }
+ if(b && printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) equalsLabel)) {
+ equalsLabel->setText(SIGN_ALMOST_EQUAL);
+ } else {
+ equalsLabel->setText("=");
+ }
+ }
+}
+
+void QalculateUnitsDialog::keyPressEvent(QKeyEvent *e) {
+ if(e->key() == Key_Return) {
+ convertClicked();
+ e->accept();
+ return;
+ }
+ KDialog::keyPressEvent(e);
+}
+
+
+#include "qalculateunitsdialog.moc"
diff --git a/src/qalculateunitsdialog.h b/src/qalculateunitsdialog.h
new file mode 100644
index 0000000..dfe9132
--- /dev/null
+++ b/src/qalculateunitsdialog.h
@@ -0,0 +1,108 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEUNITSDIALOG_H
+#define QALCULATEUNITSDIALOG_H
+
+#include <kdialog.h>
+#include <qmap.h>
+#include <qvaluevector.h>
+
+class Unit;
+class QalculateEditUnitDialog;
+class KListView;
+class QListViewItem;
+class QPushButton;
+class KLineEdit;
+class QLabel;
+class KComboBox;
+class QGroupBox;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateUnitsDialog : public KDialog {
+
+ Q_OBJECT
+
+public:
+
+ QalculateUnitsDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateUnitsDialog();
+
+ QalculateEditUnitDialog *unit_edit_dialog;
+ QString selected_category;
+ Unit *selected_unit, *selected_to_unit;
+ void addUnitTreeItem(Unit *f);
+ QMap<QListViewItem*, Unit*> unitItems;
+ QMap<QListViewItem*, QString> categoryItems;
+ QValueVector<Unit*> comboItems;
+
+ QGroupBox *convertGroup;
+ KListView *categoryView;
+ KListView *unitView;
+ QPushButton *newButton;
+ QPushButton *editButton;
+ QPushButton *deleteButton;
+ QPushButton *deactivateButton;
+ QPushButton *insertButton;
+ QPushButton *helpButton;
+ QPushButton *buttonClose;
+ QPushButton *convertResultButton;
+ QPushButton *convertButton;
+ QLabel *fromLabel, *equalsLabel;
+ KLineEdit *toEdit, *fromEdit;
+ KComboBox *toCombo;
+
+ bool block_unit_convert;
+
+public slots:
+
+ void updateUnitTree();
+ void unitDoubleClicked(QListViewItem*);
+ void unitSelected();
+ void categorySelected();
+ void insertUnit();
+ void deactivateUnit();
+ void deleteUnit();
+ void editUnit();
+ void newUnit();
+ void convertResult();
+ void convertClicked();
+ void convert();
+ void convertReversed();
+ void toUnitSelected(int);
+
+protected slots:
+
+ void slotHelp();
+
+signals:
+
+ void unitsChanged();
+ void insertRequest(Unit*);
+ void convertRequest(Unit*);
+
+protected:
+
+ void keyPressEvent(QKeyEvent *e);
+
+};
+
+#endif
diff --git a/src/qalculatevariablesdialog.cpp b/src/qalculatevariablesdialog.cpp
new file mode 100644
index 0000000..af6d024
--- /dev/null
+++ b/src/qalculatevariablesdialog.cpp
@@ -0,0 +1,493 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#include "qalculatevariablesdialog.h"
+#include "qalculate_kde_utils.h"
+#include "qalculateeditvariabledialog.h"
+#include "qalculateeditmatrixvectordialog.h"
+#include "qalculateeditunknownvariabledialog.h"
+#include "qalculateexportcsvdialog.h"
+#include <kpushbutton.h>
+#include <qsplitter.h>
+#include <qvbox.h>
+#include <qhbox.h>
+#include <klistview.h>
+#include <kmessagebox.h>
+#include <klocale.h>
+#include <qlayout.h>
+#include <kapplication.h>
+#include <kstdguiitem.h>
+
+extern tree_struct variable_cats;
+extern vector<void*> ia_variables;
+
+QalculateVariablesDialog::QalculateVariablesDialog(QWidget *parent, const char *name) : KDialog(parent, name, false) {
+
+ export_csv_dialog = NULL;
+ variable_edit_dialog = NULL;
+ matrix_edit_dialog = NULL;
+ unknown_edit_dialog = NULL;
+ selected_category = "";
+ selected_variable = NULL;
+
+ QHBoxLayout *layout = new QHBoxLayout(this, marginHint(), spacingHint());
+
+ setCaption(i18n("Variables"));
+
+ QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
+ layout->addWidget(splitter);
+
+ categoryView = new KListView(splitter);
+ categoryView->addColumn(i18n("Category"));
+
+ variableView = new KListView(splitter);
+ variableView->addColumn(i18n("Variable Name"));
+ variableView->addColumn(i18n("Value"));
+ variableView->setRootIsDecorated(false);
+
+ QVBoxLayout *buttonLayout = new QVBoxLayout(layout, spacingHint());
+
+ newButton = new QPushButton(i18n("New"), this);
+ buttonLayout->addWidget(newButton);
+ editButton = new QPushButton(i18n("Edit"), this);
+ editButton->setEnabled(false);
+ buttonLayout->addWidget(editButton);
+ deleteButton = new QPushButton(i18n("Delete"), this);
+ deleteButton->setEnabled(false);
+ buttonLayout->addWidget(deleteButton);
+ deactivateButton = new QPushButton(i18n("Deactivate"), this);
+ deactivateButton->setEnabled(false);
+ buttonLayout->addWidget(deactivateButton);
+ insertButton = new QPushButton(i18n("Insert"), this);
+ insertButton->setEnabled(false);
+ buttonLayout->addWidget(insertButton);
+ exportButton = new QPushButton(i18n("Export"), this);
+ exportButton->setEnabled(false);
+ buttonLayout->addWidget(exportButton);
+ buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
+ helpButton = new KPushButton(KStdGuiItem::help(), this);
+ buttonLayout->addWidget(helpButton);
+ buttonClose = new KPushButton(KStdGuiItem::close(), this);
+ buttonClose->setFocus();
+ buttonLayout->addWidget(buttonClose);
+
+ resize(QSize(675, 375).expandedTo(size()));
+
+ connect(buttonClose, SIGNAL(clicked()), this, SLOT(close()));
+ connect(newButton, SIGNAL(clicked()), this, SLOT(newVariable()));
+ connect(editButton, SIGNAL(clicked()), this, SLOT(editVariable()));
+ connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteVariable()));
+ connect(deactivateButton, SIGNAL(clicked()), this, SLOT(deactivateVariable()));
+ connect(insertButton, SIGNAL(clicked()), this, SLOT(insertVariable()));
+ connect(exportButton, SIGNAL(clicked()), this, SLOT(exportVariable()));
+ connect(variableView, SIGNAL(selectionChanged()), this, SLOT(variableSelected()));
+ connect(variableView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(variableDoubleClicked(QListViewItem*)));
+ connect(categoryView, SIGNAL(selectionChanged()), this, SLOT(categorySelected()));
+ connect(helpButton, SIGNAL(clicked()), this, SLOT(slotHelp()));
+
+}
+
+QalculateVariablesDialog::~QalculateVariablesDialog() {}
+
+void QalculateVariablesDialog::slotHelp() {
+ KApplication::kApplication()->invokeHelp("qalculate-managers");
+}
+
+void QalculateVariablesDialog::updateVariableTree() {
+ variableItems.clear();
+ categoryItems.clear();
+ categoryView->clear();
+ QListViewItem *i = new KListViewItem(categoryView, i18n("All")), *i2;
+ categoryItems[i] = i18n("All");
+ i->setOpen(true);
+ QString str;
+ tree_struct *item, *item2;
+ variable_cats.it = variable_cats.items.begin();
+ if(variable_cats.it != variable_cats.items.end()) {
+ item = &*variable_cats.it;
+ ++variable_cats.it;
+ item->it = item->items.begin();
+ } else {
+ item = NULL;
+ }
+ str = "";
+ i2 = i;
+ while(item) {
+ str += "/";
+ str += item->item.c_str();
+ i = new KListViewItem(i2, item->item.c_str());
+ i->setOpen(false);
+ categoryItems[i] = str;
+ if(str == selected_category) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+
+ while(item && item->it == item->items.end()) {
+ int str_i = str.findRev("/");
+ if(str_i < 0) {
+ str = "";
+ } else {
+ str.truncate(str_i);
+ }
+ item = item->parent;
+ i = i->parent();
+ i2 = i;
+ }
+ if(item) {
+ item2 = &*item->it;
+ if(item->it == item->items.begin())
+ i2 = i;
+ ++item->it;
+ item = item2;
+ item->it = item->items.begin();
+ }
+ }
+
+ if(!variable_cats.objects.empty()) {
+ //add "Uncategorized" category if there are variables without category
+ i = new KListViewItem(categoryView, i18n("Uncategorized"));
+ categoryItems[i] = i18n("Uncategorized");
+ if(selected_category == i18n("Uncategorized")) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ }
+ if(!ia_variables.empty()) {
+ //add "Inactive" category if there are inactive variables
+ i = new KListViewItem(categoryView, i18n("Inactive"));
+ categoryItems[i] = i18n("Inactive");
+ if(selected_category == i18n("Inactive")) {
+ categoryView->ensureItemVisible(i);
+ categoryView->setSelected(i, true);
+ }
+ }
+ if(!categoryView->selectedItem()) {
+ //if no category has been selected (previously selected has been renamed/deleted), select "All"
+ selected_category = i18n("All");
+ QListViewItemIterator it(categoryView);
+ if(it.current())
+ categoryView->setSelected(it.current(), true);
+ }
+}
+
+#define UPDATE_SELECTED_VARIABLE QListViewItem *i = variableView->selectedItem(); if(!i) return; selected_variable = variableItems[i]; if(!selected_variable) return;
+#define CHECK_IF_VARIABLE_STILL_THERE if(!CALCULATOR->stillHasVariable(selected_variable)) {KMessageBox::error(this, i18n("Variable does not exist anymore.")); emit variablesChanged(); return;}
+
+void QalculateVariablesDialog::exportVariable() {
+ UPDATE_SELECTED_VARIABLE
+ CHECK_IF_VARIABLE_STILL_THERE
+ if(selected_variable->isKnown()) {
+ if(!export_csv_dialog) {
+ export_csv_dialog = new QalculateExportCSVDialog(this);
+ }
+ export_csv_dialog->exportCSVFile((KnownVariable*) selected_variable);
+ }
+}
+
+
+void QalculateVariablesDialog::insertVariable() {
+ UPDATE_SELECTED_VARIABLE
+ CHECK_IF_VARIABLE_STILL_THERE
+ emit insertRequest(selected_variable);
+}
+
+
+void QalculateVariablesDialog::deactivateVariable() {
+ UPDATE_SELECTED_VARIABLE
+ CHECK_IF_VARIABLE_STILL_THERE
+ selected_variable->setActive(!selected_variable->isActive());
+ emit variablesChanged();
+}
+
+void QalculateVariablesDialog::deleteVariable() {
+ UPDATE_SELECTED_VARIABLE
+ CHECK_IF_VARIABLE_STILL_THERE
+ if(selected_variable->isLocal()) {
+ //ensure that all references are removed in Calculator
+ selected_variable->destroy();
+ //update menus and trees
+ emit variablesChanged();
+ }
+}
+
+
+void QalculateVariablesDialog::editVariable() {
+ UPDATE_SELECTED_VARIABLE
+ CHECK_IF_VARIABLE_STILL_THERE
+ Variable *v = NULL;
+ if(selected_variable->isKnown()) {
+ if(((KnownVariable*) selected_variable)->get().isVector()) {
+ if(!matrix_edit_dialog) {
+ matrix_edit_dialog = new QalculateEditMatrixVectorDialog(this);
+ }
+ v = matrix_edit_dialog->editVariable(QString::null, (KnownVariable*) selected_variable);
+ } else {
+ if(!variable_edit_dialog) {
+ variable_edit_dialog = new QalculateEditVariableDialog(this);
+ }
+ v = variable_edit_dialog->editVariable(QString::null, (KnownVariable*) selected_variable);
+ }
+ } else {
+ if(!unknown_edit_dialog) {
+ unknown_edit_dialog = new QalculateEditUnknownVariableDialog(this);
+ }
+ v = unknown_edit_dialog->editVariable(QString::null, (UnknownVariable*) selected_variable);
+ }
+ if(v) {
+ selected_variable = v;
+ if(!v->isActive()) {
+ selected_category = i18n("Inactive");
+ } else if(v->category().empty()) {
+ selected_category = i18n("Uncategorized");
+ } else {
+ selected_category = "/";
+ selected_category += v->category().c_str();
+ }
+ emit variablesChanged();
+ }
+}
+
+void QalculateVariablesDialog::newVariable() {
+ if(!variable_edit_dialog) {
+ variable_edit_dialog = new QalculateEditVariableDialog(this);
+ }
+ Variable *v = NULL;
+ if(selected_category.isEmpty() || selected_category[0] != '/') {
+ v = variable_edit_dialog->editVariable("");
+ } else {
+ QString str = selected_category;
+ str.remove(0, 1);
+ v = variable_edit_dialog->editVariable(str);
+ }
+ if(v) {
+ selected_variable = v;
+ if(!v->isActive()) {
+ selected_category = i18n("Inactive");
+ } else if(v->category().empty()) {
+ selected_category = i18n("Uncategorized");
+ } else {
+ selected_category = "/";
+ selected_category += v->category().c_str();
+ }
+ emit variablesChanged();
+ }
+}
+
+void QalculateVariablesDialog::variableDoubleClicked(QListViewItem*i) {
+ selected_variable = variableItems[i];
+ if(!selected_variable)
+ return;
+ CHECK_IF_VARIABLE_STILL_THERE
+ Variable *v = NULL;
+ if(selected_variable->isKnown()) {
+ if(((KnownVariable*) selected_variable)->get().isVector()) {
+ if(!matrix_edit_dialog) {
+ matrix_edit_dialog = new QalculateEditMatrixVectorDialog(this);
+ }
+ v = matrix_edit_dialog->editVariable(QString::null, (KnownVariable*) selected_variable);
+ } else {
+ if(!variable_edit_dialog) {
+ variable_edit_dialog = new QalculateEditVariableDialog(this);
+ }
+ v = variable_edit_dialog->editVariable(QString::null, (KnownVariable*) selected_variable);
+ }
+ } else {
+ if(!unknown_edit_dialog) {
+ unknown_edit_dialog = new QalculateEditUnknownVariableDialog(this);
+ }
+ v = unknown_edit_dialog->editVariable(QString::null, (UnknownVariable*) selected_variable);
+ }
+ if(v) {
+ selected_variable = v;
+ if(!v->isActive()) {
+ selected_category = i18n("Inactive");
+ } else if(v->category().empty()) {
+ selected_category = i18n("Uncategorized");
+ } else {
+ selected_category = "/";
+ selected_category += v->category().c_str();
+ }
+ emit variablesChanged();
+ }
+}
+
+
+void QalculateVariablesDialog::variableSelected() {
+ QListViewItem *selected = variableView->selectedItem();
+ if(selected) {
+ Variable *v = variableItems[selected];
+ if(!CALCULATOR->stillHasVariable(v)) {
+ KMessageBox::error(this, i18n("Variable does not exist anymore."));
+ selected_variable = NULL;
+ emit variablesChanged();
+ return;
+ }
+ //remember selection
+ selected_variable = v;
+ editButton->setEnabled(!is_answer_variable(v));
+ insertButton->setEnabled(v->isActive());
+ deleteButton->setEnabled(v->isLocal() && !is_answer_variable(v) && v != CALCULATOR->v_x && v != CALCULATOR->v_y && v != CALCULATOR->v_z);
+ deactivateButton->setEnabled(!is_answer_variable(v));
+ if(v->isActive())
+ deactivateButton->setText(i18n("Deactivate"));
+ else
+ deactivateButton->setText(i18n("Activate"));
+ exportButton->setEnabled(v->isKnown());
+ } else {
+ editButton->setEnabled(false);
+ insertButton->setEnabled(false);
+ deleteButton->setEnabled(false);
+ deactivateButton->setEnabled(false);
+ exportButton->setEnabled(false);
+ selected_variable = NULL;
+ }
+}
+
+void QalculateVariablesDialog::addVariableTreeItem(Variable *v) {
+ QString value;
+ if(is_answer_variable(v)) {
+ value = i18n("a previous result");
+ } else if(v->isKnown()) {
+ if(((KnownVariable*) v)->isExpression()) {
+ value = CALCULATOR->localizeExpression(((KnownVariable*) v)->expression()).c_str();
+ if(value.length() > 20) {
+ value.truncate(17);
+ value += "...";
+ }
+ } else {
+ if(((KnownVariable*) v)->get().isMatrix()) {
+ value = i18n("matrix");
+ } else if(((KnownVariable*) v)->get().isVector()) {
+ value = i18n("vector");
+ } else {
+ value = CALCULATOR->printMathStructureTimeOut(((KnownVariable*) v)->get(), 30).c_str();
+ }
+ }
+ } else {
+ if(((UnknownVariable*) v)->assumptions()) {
+ switch(((UnknownVariable*) v)->assumptions()->sign()) {
+ case ASSUMPTION_SIGN_POSITIVE: {
+ value = i18n("positive");
+ break;
+ }
+ case ASSUMPTION_SIGN_NONPOSITIVE: {
+ value = i18n("non-positive");
+ break;
+ }
+ case ASSUMPTION_SIGN_NEGATIVE: {
+ value = i18n("negative");
+ break;
+ }
+ case ASSUMPTION_SIGN_NONNEGATIVE: {
+ value = i18n("non-negative");
+ break;
+ }
+ case ASSUMPTION_SIGN_NONZERO: {
+ value = i18n("non-zero");
+ break;
+ }
+ default: {}
+ }
+ if(!value.isEmpty() && !((UnknownVariable*) v)->assumptions()->type() == ASSUMPTION_TYPE_NONE)
+ value += " ";
+ switch(((UnknownVariable*) v)->assumptions()->type()) {
+ case ASSUMPTION_TYPE_INTEGER: {
+ value += i18n("integer");
+ break;
+ }
+ case ASSUMPTION_TYPE_RATIONAL: {
+ value += i18n("rational");
+ break;
+ }
+ case ASSUMPTION_TYPE_REAL: {
+ value += i18n("real");
+ break;
+ }
+ case ASSUMPTION_TYPE_COMPLEX: {
+ value += i18n("complex");
+ break;
+ }
+ case ASSUMPTION_TYPE_NUMBER: {
+ value += i18n("number");
+ break;
+ }
+ case ASSUMPTION_TYPE_NONMATRIX: {
+ value += i18n("(not matrix)");
+ break;
+ }
+ default: {}
+ }
+ if(value.isEmpty())
+ value = i18n("unknown");
+ } else {
+ value = i18n("default assumptions");
+ }
+ }
+ QListViewItem *i = new KListViewItem(variableView, v->title(true).c_str(), value);
+ variableItems[i] = v;
+ if(v == selected_variable) {
+ variableView->setSelected(i, true);
+ }
+}
+
+
+void QalculateVariablesDialog::categorySelected() {
+ QListViewItem *selected = categoryView->selectedItem();
+ bool no_cat = false, b_all = false, b_inactive = false;
+ variableView->clear();
+ variableItems.clear();
+ if(!selected) {
+ selected_category = "";
+ variableSelected();
+ return;
+ }
+ selected_category = categoryItems[selected];
+ if(selected_category == i18n("All")) {
+ b_all = true;
+ } else if(selected_category == i18n("Uncategorized")) {
+ no_cat = true;
+ } else if(selected_category == i18n("Inactive")) {
+ b_inactive = true;
+ }
+ if(!b_all && !no_cat && !b_inactive && selected_category[0] == '/') {
+ string str = selected_category.ascii();
+ str.erase(str.begin());
+ for(size_t i = 0; i < CALCULATOR->variables.size(); i++) {
+ if(CALCULATOR->variables[i]->isActive() && CALCULATOR->variables[i]->category().substr(0, selected_category.length() - 1) == str) {
+ addVariableTreeItem(CALCULATOR->variables[i]);
+ }
+ }
+ } else {
+ string str = selected_category.ascii();
+ for(size_t i = 0; i < CALCULATOR->variables.size(); i++) {
+ if((b_inactive && !CALCULATOR->variables[i]->isActive()) || (CALCULATOR->variables[i]->isActive() && (b_all || (no_cat && CALCULATOR->variables[i]->category().empty()) || (!b_inactive && CALCULATOR->variables[i]->category() == str)))) {
+ addVariableTreeItem(CALCULATOR->variables[i]);
+ }
+ }
+ }
+ if(!selected_variable || !variableView->selectedItem()) {
+ QListViewItemIterator it(variableView);
+ if(it.current())
+ variableView->setSelected(it.current(), true);
+ }
+}
+
+
+#include "qalculatevariablesdialog.moc"
diff --git a/src/qalculatevariablesdialog.h b/src/qalculatevariablesdialog.h
new file mode 100644
index 0000000..2fa9bc5
--- /dev/null
+++ b/src/qalculatevariablesdialog.h
@@ -0,0 +1,92 @@
+/***************************************************************************
+ * Copyright (C) 2005 by Niklas Knutsson *
+ * nq@altern.org *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+#ifndef QALCULATEVARIABLESDIALOG_H
+#define QALCULATEVARIABLESDIALOG_H
+
+#include <kdialog.h>
+#include <qmap.h>
+
+class Variable;
+class QalculateEditVariableDialog;
+class QalculateEditMatrixVectorDialog;
+class QalculateEditUnknownVariableDialog;
+class QalculateExportCSVDialog;
+class KListView;
+class QListViewItem;
+class QPushButton;
+
+/**
+@author Niklas Knutsson
+*/
+class QalculateVariablesDialog : public KDialog {
+
+ Q_OBJECT
+
+public:
+
+ QalculateVariablesDialog(QWidget *parent = 0, const char *name = 0);
+ virtual ~QalculateVariablesDialog();
+
+ QalculateEditVariableDialog *variable_edit_dialog;
+ QalculateEditMatrixVectorDialog *matrix_edit_dialog;
+ QalculateEditUnknownVariableDialog *unknown_edit_dialog;
+ QalculateExportCSVDialog *export_csv_dialog;
+ QString selected_category;
+ Variable *selected_variable;
+ void addVariableTreeItem(Variable *v);
+ QMap<QListViewItem*, Variable*> variableItems;
+ QMap<QListViewItem*, QString> categoryItems;
+
+ KListView *categoryView;
+ KListView *variableView;
+ QPushButton *newButton;
+ QPushButton *editButton;
+ QPushButton *deleteButton;
+ QPushButton *deactivateButton;
+ QPushButton *insertButton;
+ QPushButton *exportButton;
+ QPushButton *helpButton;
+ QPushButton *buttonClose;
+
+public slots:
+
+ void updateVariableTree();
+ void variableDoubleClicked(QListViewItem*);
+ void variableSelected();
+ void categorySelected();
+ void exportVariable();
+ void insertVariable();
+ void deactivateVariable();
+ void deleteVariable();
+ void editVariable();
+ void newVariable();
+
+protected slots:
+
+ void slotHelp();
+
+signals:
+
+ void variablesChanged();
+ void insertRequest(Variable*);
+
+};
+
+#endif