summaryrefslogtreecommitdiffstats
path: root/kcalc
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit2bda8f7717adf28da4af0d34fb82f63d2868c31d (patch)
tree8d927b7b47a90c4adb646482a52613f58acd6f8c /kcalc
downloadtdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.tar.gz
tdeutils-2bda8f7717adf28da4af0d34fb82f63d2868c31d.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdeutils@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kcalc')
-rw-r--r--kcalc/ChangeLog387
-rw-r--r--kcalc/Makefile.am40
-rw-r--r--kcalc/README8
-rw-r--r--kcalc/TODO15
-rw-r--r--kcalc/colors.ui278
-rw-r--r--kcalc/configure.in.bot12
-rw-r--r--kcalc/configure.in.in78
-rw-r--r--kcalc/confvalues.h48
-rw-r--r--kcalc/constants.ui491
-rw-r--r--kcalc/dlabel.cpp184
-rw-r--r--kcalc/dlabel.h64
-rw-r--r--kcalc/general.ui199
-rw-r--r--kcalc/hi16-app-kcalc.pngbin0 -> 983 bytes
-rw-r--r--kcalc/hi22-app-kcalc.pngbin0 -> 1421 bytes
-rw-r--r--kcalc/hi32-app-kcalc.pngbin0 -> 2701 bytes
-rw-r--r--kcalc/hi48-app-kcalc.pngbin0 -> 5023 bytes
-rw-r--r--kcalc/hi64-app-kcalc.pngbin0 -> 6760 bytes
-rw-r--r--kcalc/hisc-app-kcalc.svgzbin0 -> 5247 bytes
-rw-r--r--kcalc/kcalc.cpp2306
-rw-r--r--kcalc/kcalc.desktop88
-rw-r--r--kcalc/kcalc.h239
-rw-r--r--kcalc/kcalc.kcfg127
-rw-r--r--kcalc/kcalc_button.cpp168
-rw-r--r--kcalc/kcalc_button.h105
-rw-r--r--kcalc/kcalc_const_button.cpp109
-rw-r--r--kcalc/kcalc_const_button.h58
-rw-r--r--kcalc/kcalc_const_menu.cpp89
-rw-r--r--kcalc/kcalc_const_menu.h55
-rw-r--r--kcalc/kcalc_core.cpp1004
-rw-r--r--kcalc/kcalc_core.h181
-rw-r--r--kcalc/kcalc_settings.kcfgc8
-rw-r--r--kcalc/kcalcdisplay.cpp608
-rw-r--r--kcalc/kcalcdisplay.h152
-rw-r--r--kcalc/kcalcrc.upd4
-rw-r--r--kcalc/kcalctype.h135
-rw-r--r--kcalc/kcalcui.rc17
-rw-r--r--kcalc/knumber/Makefile.am16
-rw-r--r--kcalc/knumber/configure.in.in73
-rw-r--r--kcalc/knumber/knumber.cpp693
-rw-r--r--kcalc/knumber/knumber.h289
-rw-r--r--kcalc/knumber/knumber_priv.cpp1083
-rw-r--r--kcalc/knumber/knumber_priv.h313
-rw-r--r--kcalc/knumber/tests/Makefile.am32
-rw-r--r--kcalc/knumber/tests/knumbertest.cpp582
-rw-r--r--kcalc/knumber/tests/knumbertest.h9
-rw-r--r--kcalc/stats.cpp196
-rw-r--r--kcalc/stats.h60
-rw-r--r--kcalc/version.h1
48 files changed, 10604 insertions, 0 deletions
diff --git a/kcalc/ChangeLog b/kcalc/ChangeLog
new file mode 100644
index 0000000..00abb5b
--- /dev/null
+++ b/kcalc/ChangeLog
@@ -0,0 +1,387 @@
+2005-12-29 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Fixed BUG 116835, BUG 118300, BUG 118909
+
+2005-10-?? Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Added arbitrary precision
+
+2005-04-30 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Fix BUG 100316
+
+2005-04-25 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Fix BUG 99817.
+
+2005-04-20 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Change C-style casts for C++ casts, removed some C-style typedefs
+
+2005-04-02 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * GUI: added statusflags to display, looks very neat (this was
+ contributed by Bernd Brandstetter; well done!)
+
+2005-03-30 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * added a Memory-Store button (contributed by Bernd Brandstetter)
+
+2005-03-29 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * fix M+/- button to change when inverse is pressed
+
+2005-03-08 Evan Teran <eteran@alum.rit.edu>
+ * updated about box to reflect my correct email address. This one is
+ permanent and will never change again
+
+2005-02-05 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * fix BUG 98522: M- button did not work at least since KDE-3.2. Shame on me, and thanks to
+ Bernd Brandstetter for reporting the bug.
+
+2004-12-21 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * added some more contants and dropped Pi-button since not needed.
+ Instead new cube and cube root button.
+
+2004-12-17 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * almost finished feature which allows to choose from list
+ of scientific constants
+
+2004-12-17 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * started implementation of a list of scientific constants
+
+2004-12-06 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * further refactoring of configuration options for const buttons
+
+2004-12-05 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * understood how kconfigxt handles indexed configuration options
+
+2004-12-03 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * moving through history is now done via undo/redo
+ this implements wish BUG 93938
+
+2004-11-23 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * improved const buttons
+
+2004-10-20 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * clean up Const-Buttons. More work still required.
+
+2004-10-16 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * improve Const-Buttons: set value by using INV-Button instead of config-menu
+
+2004-09-24 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * fixed BUG 90009: the display does not resize in vertical direction anymore
+
+2004-09-24 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * fixed small bug: switching off Logic-mode tried to change item in statusbar,
+ but item did not exist.
+
+2004-09-11 Klaus Niederkrüger <kniederk@math.uni-koeln.de> *
+ * fix bug 82433: show a check mark next to the angle mode in popup menu
+
+2004-09-10 Klaus Niederkrüger <kniederk@math.uni-koeln.de> *
+ * bundle precedence of operators and function pointers into a single
+ struct.
+
+2004-09-08 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * moved angle mode logic into GUI
+
+2004-09-04 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * reduced the number of entry points into the CalcEngine
+ Aim: enterOperation the only entry point
+
+2004-08-2? Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * added some labels and tooltips for inverse mode
+
+2004-08-2? Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * fix to BUG 74657
+ * fix to BUG 78726
+
+2004-07-30 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Square root button did not work correctly after pressing CTRL (Bug 86004)
+
+2004-07-30 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Added Accels for Const-Buttons
+
+2004-07-29 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Fixed BUG 67984 (thanks to André Wöbbeking)
+
+2004-07-17 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Fixed BUG 85357
+
+2004-06-05 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * It was not possible to paste a hex-number starting with "0x" in hex-mode, because hex-mode
+ prepended automatically "0x" leading to "0x0x...".
+
+2004-05-16 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Refactored a bit the kcalc_button code. In particular use Richtext only, when needed (a bit faster,
+ but a lot still to be done).
+
+2004-05-04 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Masked "&" for the label of the AND button, when displaying the corresponding accel.
+ Thanks to Sigrid from Trolltech.
+
+2004-04-27 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Buttons have now their own modes (like inverse Mode etc.)
+ This allows moving tooltips and labels into kcalc_button.cpp
+ instead of having everything in kcalc.cpp.
+ This needs to be cleaned up and the tooltips and labels should be
+ revised.
+
+2004-04-05 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Changed accel for OR-button from "O" to "|"
+ * More accels are visible, when "Ctrl" is used
+ * disable some buttons like "Sin", "Cos" etc., when not
+ in decimal mode
+
+2004-04-05 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Pasted numbers in Hex-Mode are now always interpreted as
+ hex-numbers (BUG 65167).
+
+2004-03-26 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Centered labels on buttons
+
+2004-03-24 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Press (and hold) CTRL-key to see accels for all
+ buttons (BUG 69850).
+
+2004-03-19 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Labels like e.g. "x^y" are drawn with QSimpleRichText
+ Need to center the labels better!!
+ * KCalcButton supports now two different labels, one for normal, one
+ for inverse mode. Switch between the two happens via a signal.
+
+2004-03-11 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Moved functions that paint e.g. "x^y" to the KCalcButton-class.
+
+2004-03-01 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Created class KCalcButton, which is now used for all QPushButtons.
+ This will allow later to change the labels more easily, if INV is
+ pressed, and mucho more...
+
+2004-02-25 Thomas Weber
+ * "x^2" and "x^y"-buttons have now superscripted labels
+ * pressing "INV"-button changes "x^2"-button to square-root etc.
+
+2004-02-25 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Changed many accels from "accel()->insert()" to
+ "button->addAccel()". Fixes BUG 75555.
+ * deactivate EE-button, when Base != DEC
+
+2004-02-10 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * First step to fix bug 66397. Changing Basemode via Popupmenu is
+ too clumsy for most programmers. Maybe backport to KDE 3.2 later,
+ once it has been tested. GUI does not look nice.
+
+2004-02-06 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Fixed bug 73437. Pasting empty clipboard made kcalc crash.
+
+2004-02-04 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Moved more accels from keyPressEvent into accels
+
+2004-01-27 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Fix paste-function: Pasting e.g. "123 \n" did not work
+ because of the trailing spaces and returns.
+
+2004-01-25 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Applied patch from Thomas Weber: Creates buttons C1-C6
+ to store constants
+
+2003-12-06 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Fix problem with several identical labels in statusbar
+ with the help of newly added statusbar->hasItem.
+
+2003-12-06 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Make Percent work the way it did in KDE-3.1 again (documentation
+ was not updated to this KDE-version, which confused me on 2003/08/28)
+
+2003-11-04 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * More reorganization and preparation for getting accels right.
+
+2003-10-31 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Split Constructor into more subfunctions.
+ To be continued.
+
+2003-10-20 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * At last the calculator window resizes, when buttons are hidden/shown
+ * Added a few extra buttons to "fill gaps".
+
+2003-10-14 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * RadioButtons for Base and Angle converted to PopUpMenu+Button
+ * Layout changed
+ * Moved ENTER form keyPressedEvent to Accel()
+
+2003-10-10 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Number buttons look like numeric keyboard (on US-keyboards that is)
+ * Initialize ToggleActions correctly
+
+2003-10-09 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Reverted the menubar stuff after several complaints.
+ Now Kcalc-GUI looks again like on 2003-09-11.
+
+2003-09-30 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Fixed bug (unitialized pointers)
+
+2003-09-26 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Moved all type of buttons to menubars, which can be hidden/showed
+ via the menubar. This is quite experimental and full of bugs.
+
+2003-09-11 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * Button groups can be switch on/off via actions.
+ This is not yet the final GUI-Layout (yes, it looks broken).
+ * Accordingly the Stat/Trig-mode has been deleted from
+ configure window.
+
+2003-09-11 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * deleted a few #includes
+
+2003-09-02 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * dropped configure-button and Help-button
+ * created menubar with standard-actions
+ * ConfigDialog is not modal anymore
+ * copy/paste/cut-standard actions applied to calc_display
+
+2003-08-28 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * created Pi-button and moved Inv-button to make space for it
+ * label of "."-button is now localized
+ * Caption is set via signal/slots
+ * Fixed "%"-mode to make it again more conformant with documentation.
+ "x^y%" does still not work. Did it ever?
+ * Number-keys are now handled by KAccel instead of keyPressEvent
+ * ConfigDialog is modal
+
+2003-08-27 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * moved result_history from CalcEngine into DispLogic
+ * reactivation of rounding towards zero for cos(90) etc.
+ * quit is done in a more KDE conformant way
+ * Caption is set via slots etc.
+
+2003-08-12 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * continued separation: now display is independent class and
+ handles everything related to itself.
+ GUI passes only information between core and display.
+
+2003-08-04 Klaus Niederkrüger <kniederk@math.uni-koeln.de>
+ * finished the separation of gui-code from the calculating core.
+ this still needs some clean-up
+
+2003-02-11 Evan Teran <emt3734@rit.edu>
+ * replaced cheasy stack with STL stack classes (it really should have been
+ two stacks, but was mushed into one with a linked list dividing content)
+ * made it use new headers (no .h) when _ISOC99_SOURCE is defined
+ * added replace current gui code with ui files to TODO list
+
+2002-05-10 Evan Teran <emt3734@rit.edu>
+ * altered makefile to remove building of it as a library then linking that
+ to a dummy object file, this was silly and caused inclusion of an uneeded
+ source file
+ * bumped version to reflect new options dialog, next version will be 2.0.0
+ as it will have many new changes/features
+
+2002-03-11 Evan Teran <emt3734@rit.edu>
+ * started work on making calculator code _seperate_ from the
+ gui code, the goal here is the make the calculating core
+ replacable with any library (hopfully with better precision) simply by
+ wrapping it in a class
+ * made it some many buttons are disabled when unavailabled (A-F) not enabled
+ unless we are in HEX mode, less confusion for users who arent familiar with
+ different bases
+ * removed some code that is never getting called
+ * why oh why are exceptions disabled in the standard config, I would like to
+ use them :(
+
+2001-10-18 Evan Teran <emt3734@rit.edu>
+ * removed configdlg.* from source tree as it is not part of the compile
+ * changed options dialog to use smarter layouts, and also fixed spinbox
+ size problem so they are now usable
+ * synced changed I made to the KDE 2.2.1 release version to match CVS
+ version which compiles under KDE 3.0 w/ QT 3.0.0
+ * made sure the clear (clear entry) button functioned properly, my minor
+ change before broke it in some situations
+
+
+2001-10-12 Evan Teran <emt3734@rit.edu>
+ * Reorganized code for all files, much more consistant now
+ * completely reworked the cvb (convert to binary) function
+ it now is sane, the last one did a rediculous amount of
+ unneeded work
+ * changed C/C++ headers to use new style as per ANSI/ISO
+ standard
+ * removed fontdlg.cpp/h from tree, not even used in compile :P
+ * made binary mode 32-bit
+ * reorganized UpdateDisplay code to make more sense
+ * found possible nasty memleak in EnterEqual
+ * now use my UNUSED macro to perform (void)var on unused parameters
+ to avoid compile warnings, much more readable this way
+ * merged setXXX functions to angle_selected/base_selected
+ then removed the setXXX functions as they no longer have any purpose
+ * changed a ton of code to use true C++ bools, makes logic
+ more clear
+ * made cvb a static member of QtCalculator instead of an ugly global
+ function
+ * changed history to use a simple vectory object instead of the storing
+ the values in a dynamically allocated QList, it was clearly leaking memory
+ as it was almost never released, this could have been fixed by enabling the
+ autodelete feature of QList...but why dynamically allocate when we are
+ storing numerical values?!? simple array with an int as an iterator :)
+ * changed error trapping from C style signal trapping, rather use exceptions
+ much cleaner that way
+ * removed un-used TopOfStack function
+ * fixed ability to enter a decimal point when in hex/oct/bin mode, those are
+ integer value only modes
+ * fixed problem with entering multiple decimal points in decimal mode
+ * changed CALCAMNT to be defined by a typedef, I did notice that at least my
+ C++ math headers are broken...functions like cos should (by newest
+ standards) use float, double, or long double versions automatically based on
+ datatype, however mine (Redhat 7.1) seems to only have the old double
+ versions, and have alternate names for these functions
+ * fixed the fact that the normal clear button seemingly did nothing
+
+
+1999-08-22 Bernd Johannes Wuebben <wuebben@math.cornell.edu>
+
+ * kcalc_core.cpp (UpdateDisplay):
+ Re-enabled the use of long double. Most if not all distributions
+ come now with a working glib math library.
+
+Mon Nov 16 18:05:01 1998 Mario Weilguni <mweilguni@kde.org>
+
+ * There was an error in the stdev forumal. Fixed.
+ * the population standard deviation had the same fault. Fixed.
+
+Mon Nov 16 18:05:01 1998 Mario Weilguni <mweilguni@kde.org>
+
+ * calculation the facturial of a too large number was delayed,
+ even though infinity was already reached. Now kcalc stops
+ calculation if infinity is reached and displays an error
+
+Mon May 4 06:28:09 1998 Bernd Johannes Wuebben <wuebben@math.cornell.edu>
+
+ * Added the comma key as an accelerator for '.'
+
+Sat Apr 18 16:26:52 1998 Bernd Johannes Wuebben <wuebben@math.cornell.edu>
+
+ * Some inverse functions didn't compute right. Wonder who broke them.
+
+Sun Feb 8 16:11:34 1998 Bernd Johannes Wuebben <wuebben@math.cornell.edu>
+
+ * removed a compiler warning
+
+Sat Nov 22 14:30:37 1997 Bernd Johannes Wuebben <wuebben@petit.cornell.edu>
+
+ * stats.cpp: fixed some bugs in the stats module
+ mean should now be correct
+ std shoudl now be correct too.
+
+Sat Sep 20 23:59:30 1997 Bernd Johannes Wuebben <wuebben@petit.cornell.edu>
+
+ * kcalc.cpp: Added statistical functions
+
+Mon Sep 15 00:34:58 1997 Bernd Johannes Wuebben <wuebben@petit.cornell.edu>
+
+ * added cut and pasted functionality
+ * implemented EE
+ * implemented result stack
+ * implemented precision and fixed precision
+ * added key bindings
+ * tooltips
+ * added configuration dialog
+
+
+Sat Aug 2 22:06:59 1997 Bernd Johannes Wuebben <wuebben@petit.cornell.edu>
+
+ * kcalc.h: clean up
+
+
diff --git a/kcalc/Makefile.am b/kcalc/Makefile.am
new file mode 100644
index 0000000..551d7d4
--- /dev/null
+++ b/kcalc/Makefile.am
@@ -0,0 +1,40 @@
+AM_CPPFLAGS= -I$(srcdir)/knumber -D_ISOC99_SOURCE $(all_includes)
+
+SUBDIRS = knumber
+
+bin_PROGRAMS =
+lib_LTLIBRARIES =
+kdeinit_LTLIBRARIES = kcalc.la
+
+kcalc_la_SOURCES = kcalc.cpp kcalc_button.cpp kcalc_const_button.cpp \
+ kcalc_const_menu.cpp kcalc_core.cpp kcalcdisplay.cpp \
+ dlabel.cpp stats.cpp colors.ui general.ui \
+ constants.ui kcalc_settings.kcfgc
+
+
+METASOURCES = AUTO
+
+noinst_HEADERS = kcalc.h kcalc_button.h kcalc_const_button.h \
+ kcalc_const_menu.h kcalc_core.h kcalcdisplay.h \
+ kcalctype.h dlabel.h stats.h
+
+kcalc_la_LDFLAGS = $(all_libraries) -module -avoid-version
+kcalc_la_LIBADD = $(LIB_KDEUI) knumber/libknumber.la
+
+KDE_ICON = kcalc
+
+xdg_apps_DATA = kcalc.desktop
+kde_kcfg_DATA = kcalc.kcfg
+
+rcdir = $(kde_datadir)/kcalc
+rc_DATA = kcalcui.rc
+
+messages: rc.cpp
+ $(XGETTEXT) *.cpp -o $(podir)/kcalc.pot
+
+updatedir = $(kde_datadir)/kconf_update
+update_DATA = kcalcrc.upd
+
+DOXYGEN_EMPTY = YES
+include $(top_srcdir)/admin/Doxyfile.am
+
diff --git a/kcalc/README b/kcalc/README
new file mode 100644
index 0000000..eb64d7c
--- /dev/null
+++ b/kcalc/README
@@ -0,0 +1,8 @@
+KCalc
+=====
+KCalc is currently covered under the GPL version 2. A copy of this
+license can be found in a file named COPYING, in the toplevel directory.
+
+Have fun with kcalc!
+
+
diff --git a/kcalc/TODO b/kcalc/TODO
new file mode 100644
index 0000000..533c7d4
--- /dev/null
+++ b/kcalc/TODO
@@ -0,0 +1,15 @@
+== ToDo ==
+* find a real fix for cos 90 != 0 bug (only in double version of compile)
+
+* get rid of dlabel.h & dlabel.cpp
+* key groups for color configuration need to be rethought
+* better to handle keys with "accel" or with "keyPressEvent"?
+
+* think about either doing RichText by hand on labels, or only draw visible buttons, to enhance startup time.
+
+Following examples from the handbook do not work anymore as explained
+in the documentation. Need to update the documentation!!
+* 22.345 Mod 8 = will give the result 6.345
+* 10.345 Lsh 3 = also gives 80
+* 16 Inv Lsh 2 = gives 4 (16 divided by 2 twice).
+* 16.999 Inv Lsh 2 = also gives 4 \ No newline at end of file
diff --git a/kcalc/colors.ui b/kcalc/colors.ui
new file mode 100644
index 0000000..26f4b28
--- /dev/null
+++ b/kcalc/colors.ui
@@ -0,0 +1,278 @@
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
+<class>Colors</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Colors</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>375</width>
+ <height>331</height>
+ </rect>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>Display Colors</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Foreground:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_ForeColor</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Background:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_BackColor</cstring>
+ </property>
+ </widget>
+ <spacer row="1" column="3">
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>110</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KColorButton" row="1" column="2">
+ <property name="name">
+ <cstring>kcfg_BackColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="color">
+ <color>
+ <red>189</red>
+ <green>255</green>
+ <blue>180</blue>
+ </color>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="0" column="2">
+ <property name="name">
+ <cstring>kcfg_ForeColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ <property name="color">
+ <color>
+ <red>0</red>
+ <green>0</green>
+ <blue>0</blue>
+ </color>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>Button Colors</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel5</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Functions:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_FunctionButtonsColor</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel7</cstring>
+ </property>
+ <property name="text">
+ <string>He&amp;xadecimals:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_HexButtonsColor</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="5" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel10</cstring>
+ </property>
+ <property name="text">
+ <string>O&amp;perations:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_OperationButtonsColor</cstring>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="0" column="2">
+ <property name="name">
+ <cstring>kcfg_FunctionButtonsColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="1" column="2">
+ <property name="name">
+ <cstring>kcfg_StatButtonsColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="4" column="2">
+ <property name="name">
+ <cstring>kcfg_MemoryButtonsColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <spacer row="3" column="3">
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>41</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KColorButton" row="5" column="2">
+ <property name="name">
+ <cstring>kcfg_OperationButtonsColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="2" column="2">
+ <property name="name">
+ <cstring>kcfg_HexButtonsColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="3" column="0">
+ <property name="name">
+ <cstring>textLabel8</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Numbers:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_NumberButtonsColor</cstring>
+ </property>
+ </widget>
+ <widget class="KColorButton" row="3" column="2">
+ <property name="name">
+ <cstring>kcfg_NumberButtonsColor</cstring>
+ </property>
+ <property name="text">
+ <string></string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>textLabel6</cstring>
+ </property>
+ <property name="text">
+ <string>St&amp;atistic functions:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_StatButtonsColor</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel" row="4" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel9</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Memory:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_MemoryButtonsColor</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<tabstops>
+ <tabstop>kcfg_ForeColor</tabstop>
+ <tabstop>kcfg_BackColor</tabstop>
+ <tabstop>kcfg_FunctionButtonsColor</tabstop>
+ <tabstop>kcfg_StatButtonsColor</tabstop>
+ <tabstop>kcfg_HexButtonsColor</tabstop>
+ <tabstop>kcfg_NumberButtonsColor</tabstop>
+ <tabstop>kcfg_MemoryButtonsColor</tabstop>
+ <tabstop>kcfg_OperationButtonsColor</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kcalc/configure.in.bot b/kcalc/configure.in.bot
new file mode 100644
index 0000000..cb7005a
--- /dev/null
+++ b/kcalc/configure.in.bot
@@ -0,0 +1,12 @@
+if test "x$kcalc_gmp_found" = "xno"; then
+ cat << EOF
+
+KCalc will not be compiled as you are missing the GMP library.
+Please install the libgmp packages
+or get GMP from http://www.swox.com/gmp/
+then run configure again
+
+EOF
+
+
+fi
diff --git a/kcalc/configure.in.in b/kcalc/configure.in.in
new file mode 100644
index 0000000..3501f1e
--- /dev/null
+++ b/kcalc/configure.in.in
@@ -0,0 +1,78 @@
+AC_CHECK_HEADERS(ieeefp.h)
+
+AC_CHECK_FUNCS(fabsl)
+
+AC_DEFUN([KDE_C_LONG_DOUBLE],
+[
+ AC_CACHE_CHECK(for long double, ac_cv_c_long_double,
+ [
+ ac_save_LIBS="$LIBS"
+ LIBS="-lm $LIBS"
+ AC_TRY_RUN(
+ [
+#define _ISOC99_SOURCE 1
+#define _GNU_SOURCE 1
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+int main() {
+/* The Stardent Vistra knows sizeof(long double), but does not support it. */
+long double foo = 1.0;
+char buffer[10];
+/* On Ultrix 4.3 cc, long double is 4 and double is 8. */
+int result = (sizeof(long double) <= sizeof(double));
+/* the following is needed for a broken printf in glibc2 */
+if (!result) {
+ foo = foo * 3;
+ sprintf(buffer,"%0.0Lf",foo);
+ result = strcmp(buffer, "3");
+/* and now something mean ;-) */
+ foo = powl(fabsl(foo), 1);
+}
+exit(result); }
+ ],
+ ac_cv_c_long_double=yes, ac_cv_c_long_double=no,
+ ac_cv_c_long_double=no
+ )
+ LIBS="$ac_save_LIBS"
+ ])
+ if test $ac_cv_c_long_double = yes; then
+ AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have support for long double in printf])
+ fi
+])
+KDE_C_LONG_DOUBLE
+
+have_l_funcs=yes
+AC_CHECK_LIB(m, asinl,,have_l_funcs=no)
+AC_CHECK_LIB(m, sqrtl,,have_l_funcs=no)
+
+if test "xyes" = "x$have_l_funcs" ; then
+ AC_DEFINE(HAVE_L_FUNCS,1,[Define if you have *l math functions (absl, ...)])
+fi
+
+AC_LANG_C
+AC_CHECK_LIB(m, isinf, [
+ AC_DEFINE_UNQUOTED(HAVE_FUNC_ISINF, 1, [Define if you have isinf])
+])
+AC_CHECK_LIB(m, round, [
+ AC_DEFINE_UNQUOTED(HAVE_FUNC_ROUND, 1, [Define if you have round])
+])
+AC_CHECK_LIB(m, roundl, [
+ AC_DEFINE_UNQUOTED(HAVE_FUNC_ROUNDL, 1, [Define if you have round])
+])
+
+kcalc_gmp_found=yes
+LIBGMP=
+KDE_CHECK_HEADER([gmp.h], [
+ KDE_CHECK_LIB(gmp, main, [
+ LIBGMP="-lgmp"
+ AC_DEFINE(HAVE_GMP, 1, [Define if you have libgmp])
+ ])
+ ],[
+ DO_NOT_COMPILE="kcalc $DO_NOT_COMPILE"
+ kcalc_gmp_found=no
+ ]
+)
+AC_SUBST(LIBGMP)
diff --git a/kcalc/confvalues.h b/kcalc/confvalues.h
new file mode 100644
index 0000000..0ec1fae
--- /dev/null
+++ b/kcalc/confvalues.h
@@ -0,0 +1,48 @@
+/*
+
+ KCalc
+
+ Copyright (C) Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+ wuebben@kde.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ */
+
+
+#ifndef _CONF_VALUES_H_
+#define _CONF_VALUES_H_
+
+typedef struct _DefStruct
+{
+ QColor forecolor;
+ QColor backcolor;
+ QColor numberButtonColor;
+ QColor functionButtonColor;
+ QColor statButtonColor;
+ QColor hexButtonColor;
+ QColor memoryButtonColor;
+ QColor operationButtonColor;
+
+ int precision;
+ int fixedprecision;
+ bool fixed;
+ bool beep;
+ bool capres;
+ QFont font;
+} DefStruct;
+
+#endif // _CONF_VALUES_H_
diff --git a/kcalc/constants.ui b/kcalc/constants.ui
new file mode 100644
index 0000000..f7c734e
--- /dev/null
+++ b/kcalc/constants.ui
@@ -0,0 +1,491 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>Constants</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>Constants</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>534</width>
+ <height>596</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>Constants</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>mainGroupBox</cstring>
+ </property>
+ <property name="title">
+ <string>Configure Constants</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox0</cstring>
+ </property>
+ <property name="title">
+ <string>C1</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_nameConstant0</cstring>
+ </property>
+ <property name="maxLength">
+ <number>6</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>70</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_valueConstant0</cstring>
+ </property>
+ <property name="maxLength">
+ <number>40</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>80</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>kPushButton0</cstring>
+ </property>
+ <property name="text">
+ <string>Predefined</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>C2</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_nameConstant1</cstring>
+ </property>
+ <property name="maxLength">
+ <number>6</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>70</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_valueConstant1</cstring>
+ </property>
+ <property name="maxLength">
+ <number>40</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer4</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>80</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>kPushButton1</cstring>
+ </property>
+ <property name="text">
+ <string>Predefined</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>C3</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_nameConstant2</cstring>
+ </property>
+ <property name="maxLength">
+ <number>6</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer5</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>70</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_valueConstant2</cstring>
+ </property>
+ <property name="maxLength">
+ <number>40</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer6</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>80</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>kPushButton2</cstring>
+ </property>
+ <property name="text">
+ <string>Predefined</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox3</cstring>
+ </property>
+ <property name="title">
+ <string>C4</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_nameConstant3</cstring>
+ </property>
+ <property name="maxLength">
+ <number>6</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer7</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>70</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_valueConstant3</cstring>
+ </property>
+ <property name="maxLength">
+ <number>40</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer8</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>80</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>kPushButton3</cstring>
+ </property>
+ <property name="text">
+ <string>Predefined</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox4</cstring>
+ </property>
+ <property name="title">
+ <string>C5</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_nameConstant4</cstring>
+ </property>
+ <property name="maxLength">
+ <number>6</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer9</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>70</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_valueConstant4</cstring>
+ </property>
+ <property name="maxLength">
+ <number>40</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer10</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>80</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>kPushButton4</cstring>
+ </property>
+ <property name="text">
+ <string>Predefined</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox5</cstring>
+ </property>
+ <property name="title">
+ <string>C6</string>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_nameConstant5</cstring>
+ </property>
+ <property name="maxLength">
+ <number>6</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer11</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>70</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLineEdit">
+ <property name="name">
+ <cstring>kcfg_valueConstant5</cstring>
+ </property>
+ <property name="maxLength">
+ <number>40</number>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer12</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>80</width>
+ <height>21</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="KPushButton">
+ <property name="name">
+ <cstring>kPushButton5</cstring>
+ </property>
+ <property name="text">
+ <string>Predefined</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer13</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<customwidgets>
+</customwidgets>
+<layoutdefaults spacing="6" margin="11"/>
+<includehints>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+ <includehint>kpushbutton.h</includehint>
+</includehints>
+</UI>
diff --git a/kcalc/dlabel.cpp b/kcalc/dlabel.cpp
new file mode 100644
index 0000000..8c6c062
--- /dev/null
+++ b/kcalc/dlabel.cpp
@@ -0,0 +1,184 @@
+/*
+ $Id$
+
+ KCalc, a scientific calculator for the X window system using the
+ Qt widget libraries, available at no cost at http://www.troll.no
+
+ Copyright (C) 1996 Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <qglobal.h>
+#include <kactioncollection.h>
+#include <kstdaction.h>
+
+#include "kcalc_settings.h"
+#include "kcalc_core.h"
+#include "dlabel.h"
+#include "dlabel.moc"
+
+
+
+DispLogic::DispLogic(QWidget *parent, const char *name,
+ KActionCollection *coll)
+ :KCalcDisplay(parent,name), _history_index(0)
+{
+ KNumber::setDefaultFloatOutput(true);
+ KNumber::setDefaultFractionalInput(true);
+ _back = KStdAction::undo(this, SLOT(history_back()), coll);
+ _forward = KStdAction::redo(this, SLOT(history_forward()), coll);
+
+ _forward->setEnabled(false);
+ _back->setEnabled(false);
+}
+
+DispLogic::~DispLogic()
+{
+}
+
+void DispLogic::changeSettings()
+{
+ QPalette pal = palette();
+
+ pal.setColor(QColorGroup::Text, KCalcSettings::foreColor());
+ pal.setColor(QColorGroup::Foreground, KCalcSettings::foreColor());
+ pal.setColor(QColorGroup::Background, KCalcSettings::backColor());
+
+ setPalette(pal);
+ setBackgroundColor(KCalcSettings::backColor());
+
+ setFont(KCalcSettings::font());
+
+ setPrecision(KCalcSettings::precision());
+
+ if(KCalcSettings::fixed() == false)
+ setFixedPrecision(-1);
+ else
+ setFixedPrecision(KCalcSettings::fixedPrecision());
+
+ setBeep(KCalcSettings::beep());
+ setGroupDigits(KCalcSettings::groupDigits());
+ updateDisplay();
+}
+
+void DispLogic::update_from_core(CalcEngine const &core,
+ bool store_result_in_history)
+{
+ bool tmp_error;
+ KNumber const & output = core.lastOutput(tmp_error);
+ if(tmp_error) sendEvent(EventError);
+ if (setAmount(output) && store_result_in_history &&
+ output != KNumber::Zero)
+ {
+ // add this latest value to our history
+ _history_list.insert(_history_list.begin(), output);
+ _history_index = 0;
+ _back->setEnabled(true);
+ _forward->setEnabled(false);
+ }
+}
+
+void DispLogic::EnterDigit(int data)
+{
+ char tmp;
+ switch(data)
+ {
+ case 0:
+ tmp = '0';
+ break;
+ case 1:
+ tmp = '1';
+ break;
+ case 2:
+ tmp = '2';
+ break;
+ case 3:
+ tmp = '3';
+ break;
+ case 4:
+ tmp = '4';
+ break;
+ case 5:
+ tmp = '5';
+ break;
+ case 6:
+ tmp = '6';
+ break;
+ case 7:
+ tmp = '7';
+ break;
+ case 8:
+ tmp = '8';
+ break;
+ case 9:
+ tmp = '9';
+ break;
+ case 0xA:
+ tmp = 'A';
+ break;
+ case 0xB:
+ tmp = 'B';
+ break;
+ case 0xC:
+ tmp = 'C';
+ break;
+ case 0xD:
+ tmp = 'D';
+ break;
+ case 0xE:
+ tmp = 'E';
+ break;
+ case 0xF:
+ tmp = 'F';
+ break;
+ default:
+ tmp = '?';
+ break;
+ }
+
+ newCharacter(tmp);
+}
+
+void DispLogic::history_forward()
+{
+ Q_ASSERT(! _history_list.empty());
+ Q_ASSERT(_history_index > 0);
+
+ _history_index --;
+
+ setAmount(_history_list[_history_index]);
+
+ if(_history_index == 0) _forward->setEnabled(false);
+
+ _back->setEnabled(true);
+}
+
+void DispLogic::history_back()
+{
+ Q_ASSERT(! _history_list.empty());
+ Q_ASSERT( _history_index < static_cast<int>(_history_list.size()) );
+
+ setAmount(_history_list[_history_index]);
+
+ _history_index ++;
+
+ if( _history_index == static_cast<int>(_history_list.size()) )
+ _back->setEnabled(false);
+ _forward->setEnabled(true);
+}
+
diff --git a/kcalc/dlabel.h b/kcalc/dlabel.h
new file mode 100644
index 0000000..a9c33c6
--- /dev/null
+++ b/kcalc/dlabel.h
@@ -0,0 +1,64 @@
+/*
+
+ $Id$
+
+ KCalc
+
+ Copyright (C) Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+ wuebben@kde.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ */
+
+
+#ifndef _D_LABEL_H_
+#define _D_LABEL_H_
+
+#include <qvaluevector.h>
+#include "kcalcdisplay.h"
+
+class CalcEngine;
+class KAction;
+class KActionCollection;
+
+class DispLogic : public KCalcDisplay
+{
+Q_OBJECT
+
+public:
+ DispLogic(QWidget *parent, const char *name,
+ KActionCollection *coll);
+ ~DispLogic();
+
+ void changeSettings();
+ void EnterDigit(int data);
+ void update_from_core(CalcEngine const &core,
+ bool store_result_in_history = false);
+
+private slots:
+ void history_back(void);
+ void history_forward(void);
+
+private:
+ QValueVector<KNumber> _history_list;
+ int _history_index;
+
+ KAction *_forward;
+ KAction *_back;
+};
+
+#endif
diff --git a/kcalc/general.ui b/kcalc/general.ui
new file mode 100644
index 0000000..7ec8b15
--- /dev/null
+++ b/kcalc/general.ui
@@ -0,0 +1,199 @@
+<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
+<class>General</class>
+<widget class="QWidget">
+ <property name="name">
+ <cstring>General</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>295</width>
+ <height>262</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>General</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Precision</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox" row="1" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>kcfg_Fixed</cstring>
+ </property>
+ <property name="text">
+ <string>Set &amp;decimal precision</string>
+ </property>
+ </widget>
+ <widget class="QLabel" row="2" column="1">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>Decimal &amp;digits:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_FixedPrecision</cstring>
+ </property>
+ </widget>
+ <widget class="QSpinBox" row="2" column="2">
+ <property name="name">
+ <cstring>kcfg_FixedPrecision</cstring>
+ </property>
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <spacer row="2" column="0">
+ <property name="name">
+ <cstring>spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>21</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QLabel" row="0" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Maximum number of digits:</string>
+ </property>
+ <property name="buddy" stdset="0">
+ <cstring>kcfg_Fixed</cstring>
+ </property>
+ </widget>
+ <spacer row="1" column="3">
+ <property name="name">
+ <cstring>spacer2</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>101</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QSpinBox" row="0" column="2">
+ <property name="name">
+ <cstring>kcfg_Precision</cstring>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ <widget class="QGroupBox">
+ <property name="name">
+ <cstring>groupBox2</cstring>
+ </property>
+ <property name="title">
+ <string>Misc</string>
+ </property>
+ <vbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_Beep</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Beep on error</string>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_CaptionResult</cstring>
+ </property>
+ <property name="text">
+ <string>Show &amp;result in window title</string>
+ </property>
+ </widget>
+ <widget class="QCheckBox">
+ <property name="name">
+ <cstring>kcfg_GroupDigits</cstring>
+ </property>
+ <property name="text">
+ <string>Group digits</string>
+ </property>
+ </widget>
+ </vbox>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>spacer3</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>31</height>
+ </size>
+ </property>
+ </spacer>
+ </vbox>
+</widget>
+<connections>
+ <connection>
+ <sender>kcfg_Fixed</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>kcfg_FixedPrecision</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+ <connection>
+ <sender>kcfg_Fixed</sender>
+ <signal>toggled(bool)</signal>
+ <receiver>textLabel1</receiver>
+ <slot>setEnabled(bool)</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>kcfg_Precision</tabstop>
+ <tabstop>kcfg_Fixed</tabstop>
+ <tabstop>kcfg_FixedPrecision</tabstop>
+ <tabstop>kcfg_Beep</tabstop>
+ <tabstop>kcfg_CaptionResult</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/kcalc/hi16-app-kcalc.png b/kcalc/hi16-app-kcalc.png
new file mode 100644
index 0000000..deb6fcd
--- /dev/null
+++ b/kcalc/hi16-app-kcalc.png
Binary files differ
diff --git a/kcalc/hi22-app-kcalc.png b/kcalc/hi22-app-kcalc.png
new file mode 100644
index 0000000..8ef1df8
--- /dev/null
+++ b/kcalc/hi22-app-kcalc.png
Binary files differ
diff --git a/kcalc/hi32-app-kcalc.png b/kcalc/hi32-app-kcalc.png
new file mode 100644
index 0000000..3406316
--- /dev/null
+++ b/kcalc/hi32-app-kcalc.png
Binary files differ
diff --git a/kcalc/hi48-app-kcalc.png b/kcalc/hi48-app-kcalc.png
new file mode 100644
index 0000000..3da02ad
--- /dev/null
+++ b/kcalc/hi48-app-kcalc.png
Binary files differ
diff --git a/kcalc/hi64-app-kcalc.png b/kcalc/hi64-app-kcalc.png
new file mode 100644
index 0000000..5ebe853
--- /dev/null
+++ b/kcalc/hi64-app-kcalc.png
Binary files differ
diff --git a/kcalc/hisc-app-kcalc.svgz b/kcalc/hisc-app-kcalc.svgz
new file mode 100644
index 0000000..4690fb4
--- /dev/null
+++ b/kcalc/hisc-app-kcalc.svgz
Binary files differ
diff --git a/kcalc/kcalc.cpp b/kcalc/kcalc.cpp
new file mode 100644
index 0000000..e7599cf
--- /dev/null
+++ b/kcalc/kcalc.cpp
@@ -0,0 +1,2306 @@
+/*
+ kCalculator, a simple scientific calculator for KDE
+
+ Copyright (C) 1996-2000 Bernd Johannes Wuebben
+ wuebben@kde.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include "../config.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+
+#include <qbuttongroup.h>
+#include <qfont.h>
+#include <qhbuttongroup.h>
+#include <qlayout.h>
+#include <qobjectlist.h>
+#include <qradiobutton.h>
+#include <qspinbox.h>
+#include <qstyle.h>
+#include <qtooltip.h>
+
+
+
+#include <kaboutdata.h>
+#include <kaccel.h>
+#include <kaction.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kcolorbutton.h>
+#include <kcolordrag.h>
+#include <kconfig.h>
+#include <kconfigdialog.h>
+#include <kdialog.h>
+#include <kfontdialog.h>
+#include <kglobal.h>
+#include <kglobalsettings.h>
+#include <kkeydialog.h>
+#include <kmenubar.h>
+#include <knotifyclient.h>
+#include <knumvalidator.h>
+#include <kpopupmenu.h>
+#include <kpushbutton.h>
+#include <kstatusbar.h>
+#include <kstdaction.h>
+
+#include "dlabel.h"
+#include "kcalc.h"
+#include "kcalc_const_menu.h"
+#include "version.h"
+#include "general.h"
+#include "colors.h"
+#include "constants.h"
+#include <kaccelmanager.h>
+#include "kcalc_settings.h"
+
+
+
+static const char description[] = I18N_NOOP("KDE Calculator");
+static const char version[] = KCALCVERSION;
+
+
+KCalculator::KCalculator(QWidget *parent, const char *name)
+ : KMainWindow(parent, name), inverse(false),
+ hyp_mode(false), memory_num(0.0), calc_display(NULL),
+ mInternalSpacing(4), core()
+{
+ /* central widget to contain all the elements */
+ QWidget *central = new QWidget(this);
+ setCentralWidget(central);
+ KAcceleratorManager::setNoAccel( central );
+
+ // Detect color change
+ connect(kapp,SIGNAL(kdisplayPaletteChanged()), SLOT(set_colors()));
+
+ calc_display = new DispLogic(central, "display", actionCollection());
+
+ setupMainActions();
+
+ setupStatusbar();
+
+ createGUI();
+
+ // How can I make the toolBar not appear at all?
+ // This is not a nice solution.
+ toolBar()->close();
+
+ // Create Button to select BaseMode
+ BaseChooseGroup = new QHButtonGroup(i18n("Base"), central);
+ connect(BaseChooseGroup, SIGNAL(clicked(int)), SLOT(slotBaseSelected(int)));
+ BaseChooseGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, false);
+
+
+ pbBaseChoose[0] = new QRadioButton(i18n("He&x"), BaseChooseGroup,
+ "Hexadecimal-Switch");
+ QToolTip::add(pbBaseChoose[0], i18n("Switch base to hexadecimal."));
+
+ pbBaseChoose[1] = new QRadioButton(i18n("&Dec"), BaseChooseGroup,
+ "Decimal-Switch");
+ QToolTip::add(pbBaseChoose[1], i18n("Switch base to decimal."));
+
+ pbBaseChoose[2] = new QRadioButton(i18n("&Oct"), BaseChooseGroup,
+ "Octal-Switch");
+ QToolTip::add(pbBaseChoose[2], i18n("Switch base to octal."));
+
+ pbBaseChoose[3] = new QRadioButton(i18n("&Bin"), BaseChooseGroup,
+ "Binary-Switch");
+ QToolTip::add(pbBaseChoose[3], i18n("Switch base to binary."));
+
+
+ // Create Button to select AngleMode
+ pbAngleChoose = new QPushButton(i18n("&Angle"),
+ central, "ChooseAngleMode-Button");
+ QToolTip::add(pbAngleChoose, i18n("Choose the unit for the angle measure"));
+ pbAngleChoose->setAutoDefault(false);
+
+ KPopupMenu *angle_menu = new KPopupMenu(pbAngleChoose, "AngleMode-Selection-Menu");
+ angle_menu->insertItem(i18n("Degrees"), 0);
+ angle_menu->insertItem(i18n("Radians"), 1);
+ angle_menu->insertItem(i18n("Gradians"), 2);
+
+ angle_menu->setCheckable(true);
+ connect(angle_menu, SIGNAL(activated(int)), SLOT(slotAngleSelected(int)));
+ pbAngleChoose->setPopup(angle_menu);
+
+
+
+ pbInv = new KCalcButton("Inv", central, "Inverse-Button",
+ i18n("Inverse mode"));
+ pbInv->setAccel(Key_I);
+ connect(pbInv, SIGNAL(toggled(bool)), SLOT(slotInvtoggled(bool)));
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbInv, SLOT(slotSetAccelDisplayMode(bool)));
+ pbInv->setToggleButton(true);
+
+ //
+ // Create Calculator Buttons
+ //
+
+ // First the widgets that are the parents of the buttons
+ mSmallPage = new QWidget(central);
+ mLargePage = new QWidget(central);
+ mNumericPage = setupNumericKeys(central);
+
+ setupLogicKeys(mSmallPage);
+ setupStatisticKeys(mSmallPage);
+ setupScientificKeys(mSmallPage);
+ setupConstantsKeys(mSmallPage);
+
+
+ pbMod = new KCalcButton(mSmallPage, "Modulo-Button");
+ pbMod->addMode(ModeNormal, "Mod", i18n("Modulo"));
+ pbMod->addMode(ModeInverse, "IntDiv", i18n("Integer division"));
+ pbMod->setAccel(Key_Colon);
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ pbMod, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbMod, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbMod, SIGNAL(clicked(void)), SLOT(slotModclicked(void)));
+
+ pbReci = new KCalcButton(mSmallPage, "Reciprocal-Button");
+ pbReci->addMode(ModeNormal, "1/x", i18n("Reciprocal"));
+ pbReci->setAccel(Key_R);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbReci, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbReci, SIGNAL(clicked(void)), SLOT(slotReciclicked(void)));
+
+ pbFactorial = new KCalcButton(mSmallPage, "Factorial-Button");
+ pbFactorial->addMode(ModeNormal, "x!", i18n("Factorial"));
+ pbFactorial->setAccel(Key_Exclam);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbFactorial, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbFactorial, SIGNAL(clicked(void)),SLOT(slotFactorialclicked(void)));
+
+ // Representation of x^2 is moved to the function
+ // changeRepresentation() that paints the letters When
+ // pressing the INV Button a sqrt symbol will be drawn on that
+ // button
+ pbSquare = new KCalcButton(mSmallPage, "Square-Button");
+ pbSquare->addMode(ModeNormal, "x<sup>2</sup>", i18n("Square"), true);
+ pbSquare->addMode(ModeInverse, "x<sup>3</sup>", i18n("Third power"), true);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbSquare, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ pbSquare, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(pbSquare, SIGNAL(clicked(void)), SLOT(slotSquareclicked(void)));
+
+ pbRoot = new KSquareButton(mSmallPage, "Square-Button");
+ pbRoot->addMode(ModeNormal, "sqrt(x)", i18n("Square root"));
+ pbRoot->addMode(ModeInverse, "sqrt[3](x)", i18n("Cube root"));
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbRoot, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ pbRoot, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(pbRoot, SIGNAL(clicked(void)), SLOT(slotRootclicked(void)));
+
+
+ // Representation of x^y is moved to the function
+ // changeRepresentation() that paints the letters When
+ // pressing the INV Button y^x will be drawn on that button
+ pbPower = new KCalcButton(mSmallPage, "Power-Button");
+ pbPower->addMode(ModeNormal, "x<sup>y</sup>", i18n("x to the power of y"), true);
+ pbPower->addMode(ModeInverse, "x<sup>1/y</sup>", i18n("x to the power of 1/y"), true);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbPower, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ pbPower, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ pbPower->setAccel(Key_AsciiCircum);
+ connect(pbPower, SIGNAL(clicked(void)), SLOT(slotPowerclicked(void)));
+
+
+ //
+ // All these layouts are needed because all the groups have their
+ // own size per row so we can't use one huge QGridLayout (mosfet)
+ //
+ QGridLayout *smallBtnLayout = new QGridLayout(mSmallPage, 6, 4, 0,
+ mInternalSpacing);
+ QGridLayout *largeBtnLayout = new QGridLayout(mLargePage, 5, 2, 0,
+ mInternalSpacing);
+
+ QHBoxLayout *topLayout = new QHBoxLayout();
+ QHBoxLayout *btnLayout = new QHBoxLayout();
+
+ // bring them all together
+ QVBoxLayout *mainLayout = new QVBoxLayout(central, mInternalSpacing,
+ mInternalSpacing);
+
+ mainLayout->addLayout(topLayout);
+ mainLayout->addLayout(btnLayout);
+
+ // button layout
+ btnLayout->addWidget(mSmallPage, 0, AlignTop);
+ btnLayout->addSpacing(2*mInternalSpacing);
+ btnLayout->addWidget(mNumericPage, 0, AlignTop);
+ btnLayout->addSpacing(2*mInternalSpacing);
+ btnLayout->addWidget(mLargePage, 0, AlignTop);
+
+ // small button layout
+ smallBtnLayout->addWidget(pbStat["NumData"], 0, 0);
+ smallBtnLayout->addWidget(pbScientific["HypMode"], 0, 1);
+ smallBtnLayout->addWidget(pbLogic["AND"], 0, 2);
+ smallBtnLayout->addWidget(pbMod, 0, 3);
+ smallBtnLayout->addWidget(NumButtonGroup->find(0xA), 0, 4);
+ smallBtnLayout->addWidget(pbConstant[0], 0, 5);
+
+ smallBtnLayout->addWidget(pbStat["Mean"], 1, 0);
+ smallBtnLayout->addWidget(pbScientific["Sine"], 1, 1);
+ smallBtnLayout->addWidget(pbLogic["OR"], 1, 2);
+ smallBtnLayout->addWidget(pbReci, 1, 3);
+ smallBtnLayout->addWidget(NumButtonGroup->find(0xB), 1, 4);
+ smallBtnLayout->addWidget(pbConstant[1], 1, 5);
+
+ smallBtnLayout->addWidget(pbStat["StandardDeviation"], 2, 0);
+ smallBtnLayout->addWidget(pbScientific["Cosine"], 2, 1);
+ smallBtnLayout->addWidget(pbLogic["XOR"], 2, 2);
+ smallBtnLayout->addWidget(pbFactorial, 2, 3);
+ smallBtnLayout->addWidget(NumButtonGroup->find(0xC), 2, 4);
+ smallBtnLayout->addWidget(pbConstant[2], 2, 5);
+
+ smallBtnLayout->addWidget(pbStat["Median"], 3, 0);
+ smallBtnLayout->addWidget(pbScientific["Tangent"], 3, 1);
+ smallBtnLayout->addWidget(pbLogic["LeftShift"], 3, 2);
+ smallBtnLayout->addWidget(pbSquare, 3, 3);
+ smallBtnLayout->addWidget(NumButtonGroup->find(0xD), 3, 4);
+ smallBtnLayout->addWidget(pbConstant[3], 3, 5);
+
+ smallBtnLayout->addWidget(pbStat["InputData"], 4, 0);
+ smallBtnLayout->addWidget(pbScientific["Log10"], 4, 1);
+ smallBtnLayout->addWidget(pbLogic["RightShift"], 4, 2);
+ smallBtnLayout->addWidget(pbRoot, 4, 3);
+ smallBtnLayout->addWidget(NumButtonGroup->find(0xE), 4, 4);
+ smallBtnLayout->addWidget(pbConstant[4], 4, 5);
+
+ smallBtnLayout->addWidget(pbStat["ClearData"], 5, 0);
+ smallBtnLayout->addWidget(pbScientific["LogNatural"], 5, 1);
+ smallBtnLayout->addWidget(pbLogic["One-Complement"], 5, 2);
+ smallBtnLayout->addWidget(pbPower, 5, 3);
+ smallBtnLayout->addWidget(NumButtonGroup->find(0xF), 5, 4);
+ smallBtnLayout->addWidget(pbConstant[5], 5, 5);
+
+ smallBtnLayout->setRowStretch(0, 0);
+ smallBtnLayout->setRowStretch(1, 0);
+ smallBtnLayout->setRowStretch(2, 0);
+ smallBtnLayout->setRowStretch(3, 0);
+ smallBtnLayout->setRowStretch(4, 0);
+ smallBtnLayout->setRowStretch(5, 0);
+
+ // large button layout
+ largeBtnLayout->addWidget(pbClear, 0, 0);
+ largeBtnLayout->addWidget(pbAC, 0, 1);
+
+ largeBtnLayout->addWidget(pbParenOpen, 1, 0);
+ largeBtnLayout->addWidget(pbParenClose, 1, 1);
+
+ largeBtnLayout->addWidget(pbMemRecall, 2, 0);
+ largeBtnLayout->addWidget(pbMemStore, 2, 1);
+
+ largeBtnLayout->addWidget(pbMemPlusMinus, 3, 0);
+ largeBtnLayout->addWidget(pbMC, 3, 1);
+
+ largeBtnLayout->addWidget(pbPercent, 4, 0);
+ largeBtnLayout->addWidget(pbPlusMinus, 4, 1);
+
+ // top layout
+ topLayout->addWidget(pbAngleChoose);
+ topLayout->addWidget(BaseChooseGroup);
+ topLayout->addStretch();
+ topLayout->addWidget(pbInv);
+ mainLayout->insertWidget(0, calc_display);
+
+ mFunctionButtonList.append(pbScientific["HypMode"]);
+ mFunctionButtonList.append(pbInv);
+ mFunctionButtonList.append(pbRoot);
+ mFunctionButtonList.append(pbScientific["Sine"]);
+ mFunctionButtonList.append(pbPlusMinus);
+ mFunctionButtonList.append(pbScientific["Cosine"]);
+ mFunctionButtonList.append(pbReci);
+ mFunctionButtonList.append(pbScientific["Tangent"]);
+ mFunctionButtonList.append(pbFactorial);
+ mFunctionButtonList.append(pbScientific["Log10"]);
+ mFunctionButtonList.append(pbSquare);
+ mFunctionButtonList.append(pbScientific["LogNatural"]);
+ mFunctionButtonList.append(pbPower);
+
+ mMemButtonList.append(pbEE);
+ mMemButtonList.append(pbMemRecall);
+ mMemButtonList.append(pbMemPlusMinus);
+ mMemButtonList.append(pbMemStore);
+ mMemButtonList.append(pbMC);
+ mMemButtonList.append(pbClear);
+ mMemButtonList.append(pbAC);
+
+ mOperationButtonList.append(pbX);
+ mOperationButtonList.append(pbParenOpen);
+ mOperationButtonList.append(pbParenClose);
+ mOperationButtonList.append(pbLogic["AND"]);
+ mOperationButtonList.append(pbDivision);
+ mOperationButtonList.append(pbLogic["OR"]);
+ mOperationButtonList.append(pbLogic["XOR"]);
+ mOperationButtonList.append(pbPlus);
+ mOperationButtonList.append(pbMinus);
+ mOperationButtonList.append(pbLogic["LeftShift"]);
+ mOperationButtonList.append(pbLogic["RightShift"]);
+ mOperationButtonList.append(pbPeriod);
+ mOperationButtonList.append(pbEqual);
+ mOperationButtonList.append(pbPercent);
+ mOperationButtonList.append(pbLogic["One-Complement"]);
+ mOperationButtonList.append(pbMod);
+
+ set_colors();
+ // Show the result in the app's caption in taskbar (wishlist - bug #52858)
+ if (KCalcSettings::captionResult() == true)
+ connect(calc_display,
+ SIGNAL(changedText(const QString &)),
+ SLOT(setCaption(const QString &)));
+ calc_display->changeSettings();
+ set_precision();
+
+ // Switch to decimal
+ resetBase();
+ slotAngleSelected(0);
+
+ updateGeometry();
+
+ adjustSize();
+ setFixedSize(sizeHint());
+
+ UpdateDisplay(true);
+
+ // Read and set button groups
+
+ actionStatshow->setChecked(KCalcSettings::showStat());
+ slotStatshow(KCalcSettings::showStat());
+
+ actionScientificshow->setChecked(KCalcSettings::showScientific());
+ slotScientificshow(KCalcSettings::showScientific());
+
+ actionLogicshow->setChecked(KCalcSettings::showLogic());
+ slotLogicshow(KCalcSettings::showLogic());
+
+ actionConstantsShow->setChecked(KCalcSettings::showConstants());
+ slotConstantsShow(KCalcSettings::showConstants());
+}
+
+KCalculator::~KCalculator()
+{
+ KCalcSettings::writeConfig();
+ delete calc_display;
+}
+
+void KCalculator::setupMainActions(void)
+{
+ // file menu
+ KStdAction::quit(this, SLOT(close()), actionCollection());
+
+ // edit menu
+ KStdAction::cut(calc_display, SLOT(slotCut()), actionCollection());
+ KStdAction::copy(calc_display, SLOT(slotCopy()), actionCollection());
+ KStdAction::paste(calc_display, SLOT(slotPaste()), actionCollection());
+
+ // settings menu
+ actionStatshow = new KToggleAction(i18n("&Statistic Buttons"), 0,
+ actionCollection(), "show_stat");
+ actionStatshow->setChecked(true);
+ connect(actionStatshow, SIGNAL(toggled(bool)),
+ SLOT(slotStatshow(bool)));
+
+ actionScientificshow = new KToggleAction(i18n("Science/&Engineering Buttons"),
+ 0, actionCollection(), "show_science");
+ actionScientificshow->setChecked(true);
+ connect(actionScientificshow, SIGNAL(toggled(bool)),
+ SLOT(slotScientificshow(bool)));
+
+ actionLogicshow = new KToggleAction(i18n("&Logic Buttons"), 0,
+ actionCollection(), "show_logic");
+ actionLogicshow->setChecked(true);
+ connect(actionLogicshow, SIGNAL(toggled(bool)),
+ SLOT(slotLogicshow(bool)));
+
+ actionConstantsShow = new KToggleAction(i18n("&Constants Buttons"), 0,
+ actionCollection(), "show_constants");
+ actionConstantsShow->setChecked(true);
+ connect(actionConstantsShow, SIGNAL(toggled(bool)),
+ SLOT(slotConstantsShow(bool)));
+
+
+ (void) new KAction(i18n("&Show All"), 0, this, SLOT(slotShowAll()),
+ actionCollection(), "show_all");
+
+ (void) new KAction(i18n("&Hide All"), 0, this, SLOT(slotHideAll()),
+ actionCollection(), "hide_all");
+
+ KStdAction::preferences(this, SLOT(showSettings()), actionCollection());
+
+ KStdAction::keyBindings(guiFactory(), SLOT(configureShortcuts()),
+actionCollection());
+
+}
+
+void KCalculator::setupStatusbar(void)
+{
+ // Status bar contents
+ statusBar()->insertFixedItem(" NORM ", 0, true);
+ statusBar()->setItemAlignment(0, AlignCenter);
+
+ statusBar()->insertFixedItem(" HEX ", 1, true);
+ statusBar()->setItemAlignment(1, AlignCenter);
+
+ statusBar()->insertFixedItem(" DEG ", 2, true);
+ statusBar()->setItemAlignment(2, AlignCenter);
+
+ statusBar()->insertFixedItem(" \xa0\xa0 ", 3, true); // Memory indicator
+ statusBar()->setItemAlignment(3, AlignCenter);
+}
+
+QWidget* KCalculator::setupNumericKeys(QWidget *parent)
+{
+ Q_CHECK_PTR(mSmallPage);
+ Q_CHECK_PTR(mLargePage);
+
+ QWidget *thisPage = new QWidget(parent);
+
+ KCalcButton *tmp_pb;
+
+ NumButtonGroup = new QButtonGroup(0, "Num-Button-Group");
+ connect(NumButtonGroup, SIGNAL(clicked(int)),
+ SLOT(slotNumberclicked(int)));
+
+ tmp_pb = new KCalcButton("0", thisPage, "0-Button");
+ tmp_pb->setAccel(Key_0);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 0);
+
+ tmp_pb = new KCalcButton("1", thisPage, "1-Button");
+ tmp_pb->setAccel(Key_1);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 1);
+
+ tmp_pb = new KCalcButton("2", thisPage, "2-Button");
+ tmp_pb->setAccel(Key_2);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 2);
+
+ tmp_pb = new KCalcButton("3", thisPage, "3-Button");
+ tmp_pb->setAccel(Key_3);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 3);
+
+ tmp_pb = new KCalcButton("4", thisPage, "4-Button");
+ tmp_pb->setAccel(Key_4);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 4);
+
+ tmp_pb = new KCalcButton("5", thisPage, "5-Button");
+ tmp_pb->setAccel(Key_5);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 5);
+
+ tmp_pb = new KCalcButton("6", thisPage, "6-Button");
+ tmp_pb->setAccel(Key_6);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 6);
+
+ tmp_pb = new KCalcButton("7", thisPage, "7-Button");
+ tmp_pb->setAccel(Key_7);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 7);
+
+ tmp_pb = new KCalcButton("8", thisPage, "8-Button");
+ tmp_pb->setAccel(Key_8);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 8);
+
+ tmp_pb = new KCalcButton("9", thisPage, "9-Button");
+ tmp_pb->setAccel(Key_9);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 9);
+
+ pbEE = new KCalcButton(thisPage, "EE-Button");
+ pbEE->addMode(ModeNormal, "x<small>" "\xb7" "10</small><sup>y</sup>",
+ i18n("Exponent"), true);
+ pbEE->setAccel(Key_E);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbEE, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbEE, SIGNAL(clicked(void)), SLOT(slotEEclicked(void)));
+
+ pbParenClose = new KCalcButton(")", mLargePage, "ParenClose-Button");
+ pbParenClose->setAccel(Key_ParenRight);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbParenClose, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbParenClose,SIGNAL(clicked(void)),SLOT(slotParenCloseclicked(void)));
+
+ pbX = new KCalcButton("X", thisPage, "Multiply-Button", i18n("Multiplication"));
+ pbX->setAccel(Key_multiply);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbX, SLOT(slotSetAccelDisplayMode(bool)));
+ accel()->insert("Pressed '*'", i18n("Pressed Multiplication-Button"),
+ 0, Key_Asterisk, pbX, SLOT(animateClick()));
+ connect(pbX, SIGNAL(clicked(void)), SLOT(slotXclicked(void)));
+
+ pbDivision = new KCalcButton("/", thisPage, "Division-Button", i18n("Division"));
+ pbDivision->setAccel(Key_Slash);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbDivision, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbDivision, SIGNAL(clicked(void)), SLOT(slotDivisionclicked(void)));
+
+ pbPlus = new KCalcButton("+", thisPage, "Plus-Button", i18n("Addition"));
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbPlus, SLOT(slotSetAccelDisplayMode(bool)));
+ pbPlus->setAccel(Key_Plus);
+ connect(pbPlus, SIGNAL(clicked(void)), SLOT(slotPlusclicked(void)));
+
+ pbMinus = new KCalcButton("-", thisPage, "Minus-Button", i18n("Subtraction"));
+ pbMinus->setAccel(Key_Minus);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbMinus, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbMinus, SIGNAL(clicked(void)), SLOT(slotMinusclicked(void)));
+
+ pbPeriod = new KCalcButton(KGlobal::locale()->decimalSymbol(), thisPage,
+ "Period-Button", i18n("Decimal point"));
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbPeriod, SLOT(slotSetAccelDisplayMode(bool)));
+ accel()->insert("Decimal Point (Period)", i18n("Pressed Decimal Point"),
+ 0, Key_Period, pbPeriod, SLOT(animateClick()));
+ accel()->insert("Decimal Point (Comma)", i18n("Pressed Decimal Point"),
+ 0, Key_Comma, pbPeriod, SLOT(animateClick()));
+ connect(pbPeriod, SIGNAL(clicked(void)), SLOT(slotPeriodclicked(void)));
+
+ pbEqual = new KCalcButton("=", thisPage, "Equal-Button", i18n("Result"));
+ pbEqual->setAccel(Key_Enter);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbEqual, SLOT(slotSetAccelDisplayMode(bool)));
+ accel()->insert("Entered Equal", i18n("Pressed Equal-Button"),
+ 0, Key_Equal, pbEqual, SLOT(animateClick()));
+ accel()->insert("Entered Return", i18n("Pressed Equal-Button"),
+ 0, Key_Return, pbEqual, SLOT(animateClick()));
+ connect(pbEqual, SIGNAL(clicked(void)), SLOT(slotEqualclicked(void)));
+
+
+ QGridLayout *thisLayout = new QGridLayout(thisPage, 5, 4, 0,
+ mInternalSpacing);
+
+ // large button layout
+ thisLayout->addWidget(pbEE, 0, 0);
+ thisLayout->addWidget(pbDivision, 0, 1);
+ thisLayout->addWidget(pbX, 0, 2);
+ thisLayout->addWidget(pbMinus, 0, 3);
+
+ thisLayout->addWidget(NumButtonGroup->find(7), 1, 0);
+ thisLayout->addWidget(NumButtonGroup->find(8), 1, 1);
+ thisLayout->addWidget(NumButtonGroup->find(9), 1, 2);
+ thisLayout->addMultiCellWidget(pbPlus, 1, 2, 3, 3);
+
+ thisLayout->addWidget(NumButtonGroup->find(4), 2, 0);
+ thisLayout->addWidget(NumButtonGroup->find(5), 2, 1);
+ thisLayout->addWidget(NumButtonGroup->find(6), 2, 2);
+ //thisLayout->addMultiCellWidget(pbPlus, 1, 2, 3, 3);
+
+ thisLayout->addWidget(NumButtonGroup->find(1), 3, 0);
+ thisLayout->addWidget(NumButtonGroup->find(2), 3, 1);
+ thisLayout->addWidget(NumButtonGroup->find(3), 3, 2);
+ thisLayout->addMultiCellWidget(pbEqual, 3, 4, 3, 3);
+
+ thisLayout->addMultiCellWidget(NumButtonGroup->find(0), 4, 4, 0, 1);
+ thisLayout->addWidget(pbPeriod, 4, 2);
+ //thisLayout->addMultiCellWidget(pbEqual, 3, 4, 3, 3);
+
+ thisLayout->addColSpacing(0,10);
+ thisLayout->addColSpacing(1,10);
+ thisLayout->addColSpacing(2,10);
+ thisLayout->addColSpacing(3,10);
+ thisLayout->addColSpacing(4,10);
+
+
+ pbMemRecall = new KCalcButton("MR", mLargePage, "MemRecall-Button", i18n("Memory recall"));
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbMemRecall, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbMemRecall, SIGNAL(clicked(void)),
+ SLOT(slotMemRecallclicked(void)));
+ pbMemRecall->setDisabled(true); // At start, there is nothing in memory
+
+ pbMemPlusMinus = new KCalcButton(mLargePage, "MPlusMinus-Button");
+ pbMemPlusMinus->addMode(ModeNormal, "M+", i18n("Add display to memory"));
+ pbMemPlusMinus->addMode(ModeInverse, "M-", i18n("Subtract from memory"));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ pbMemPlusMinus, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbMemPlusMinus, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbMemPlusMinus,SIGNAL(clicked(void)),
+ SLOT(slotMemPlusMinusclicked(void)));
+
+ pbMemStore = new KCalcButton("MS", mLargePage, "MemStore-Button",
+ i18n("Memory store"));
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbMemStore, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbMemStore, SIGNAL(clicked(void)), SLOT(slotMemStoreclicked(void)));
+
+
+ pbMC = new KCalcButton("MC", mLargePage, "MemClear-Button", i18n("Clear memory"));
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbMC, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbMC, SIGNAL(clicked(void)), SLOT(slotMCclicked(void)));
+
+ pbClear = new KCalcButton("C", mLargePage, "Clear-Button", i18n("Clear"));
+ pbClear->setAccel(Key_Prior);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbClear, SLOT(slotSetAccelDisplayMode(bool)));
+ accel()->insert("Entered 'ESC'", i18n("Pressed ESC-Button"), 0,
+ Key_Escape, pbClear, SLOT(animateClick()));
+ connect(pbClear, SIGNAL(clicked(void)), SLOT(slotClearclicked(void)));
+
+ pbAC = new KCalcButton("AC", mLargePage, "AC-Button", i18n("Clear all"));
+ pbAC->setAccel(Key_Delete);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbAC, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbAC, SIGNAL(clicked(void)), SLOT(slotACclicked(void)));
+
+ pbParenOpen = new KCalcButton("(", mLargePage, "ParenOpen-Button");
+ pbParenOpen->setAccel(Key_ParenLeft);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbParenOpen, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbParenOpen, SIGNAL(clicked(void)),SLOT(slotParenOpenclicked(void)));
+
+ pbPercent = new KCalcButton("%", mLargePage, "Percent-Button", i18n("Percent"));
+ pbPercent->setAccel(Key_Percent);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbPercent, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbPercent, SIGNAL(clicked(void)), SLOT(slotPercentclicked(void)));
+
+ pbPlusMinus = new KCalcButton("\xb1", mLargePage, "Sign-Button", i18n("Change sign"));
+ pbPlusMinus->setAccel(Key_Backslash);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ pbPlusMinus, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(pbPlusMinus, SIGNAL(clicked(void)), SLOT(slotPlusMinusclicked(void)));
+
+
+ tmp_pb = new KCalcButton("A", mSmallPage, "A-Button");
+ tmp_pb->setAccel(Key_A);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 0xA);
+
+ tmp_pb = new KCalcButton("B", mSmallPage, "B-Button");
+ tmp_pb->setAccel(Key_B);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 0xB);
+
+ tmp_pb = new KCalcButton("C", mSmallPage, "C-Button");
+ tmp_pb->setAccel(Key_C);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 0xC);
+
+ tmp_pb = new KCalcButton("D", mSmallPage, "D-Button");
+ tmp_pb->setAccel(Key_D);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 0xD);
+
+ tmp_pb = new KCalcButton("E", mSmallPage, "E-Button");
+ tmp_pb->setAccel(Key_E);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 0xE);
+
+ tmp_pb = new KCalcButton("F", mSmallPage, "F-Button");
+ tmp_pb->setAccel(Key_F);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ NumButtonGroup->insert(tmp_pb, 0xF);
+
+ return thisPage;
+}
+
+void KCalculator::setupLogicKeys(QWidget *parent)
+{
+ Q_CHECK_PTR(parent);
+
+ KCalcButton *tmp_pb;
+
+ tmp_pb = new KCalcButton("AND", parent, "AND-Button", i18n("Bitwise AND"));
+ pbLogic.insert("AND", tmp_pb);
+ tmp_pb->setAccel(Key_Ampersand);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotANDclicked(void)));
+
+ tmp_pb = new KCalcButton("OR", parent, "OR-Button", i18n("Bitwise OR"));
+ pbLogic.insert("OR", tmp_pb);
+ tmp_pb->setAccel(Key_Bar);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotORclicked(void)));
+
+ tmp_pb = new KCalcButton("XOR", parent, "XOR-Button", i18n("Bitwise XOR"));
+ pbLogic.insert("XOR", tmp_pb);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotXORclicked(void)));
+
+ tmp_pb = new KCalcButton("Cmp", parent, "One-Complement-Button",
+ i18n("One's complement"));
+ pbLogic.insert("One-Complement", tmp_pb);
+ tmp_pb->setAccel(Key_AsciiTilde);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotNegateclicked(void)));
+
+ tmp_pb = new KCalcButton("Lsh", parent, "LeftBitShift-Button",
+ i18n("Left bit shift"));
+ tmp_pb->setAccel(Key_Less);
+ pbLogic.insert("LeftShift", tmp_pb);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)),
+ SLOT(slotLeftShiftclicked(void)));
+
+ tmp_pb = new KCalcButton("Rsh", parent, "RightBitShift-Button",
+ i18n("Right bit shift"));
+ tmp_pb->setAccel(Key_Greater);
+ pbLogic.insert("RightShift", tmp_pb);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)),
+ SLOT(slotRightShiftclicked(void)));
+}
+
+void KCalculator::setupScientificKeys(QWidget *parent)
+{
+ Q_CHECK_PTR(parent);
+
+ KCalcButton *tmp_pb;
+
+ tmp_pb = new KCalcButton("Hyp", parent, "Hyp-Button", i18n("Hyperbolic mode"));
+ pbScientific.insert("HypMode", tmp_pb);
+ tmp_pb->setAccel(Key_H);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(tmp_pb, SIGNAL(toggled(bool)), SLOT(slotHyptoggled(bool)));
+ tmp_pb->setToggleButton(true);
+
+ tmp_pb = new KCalcButton(parent, "Sin-Button");
+ pbScientific.insert("Sine", tmp_pb);
+ tmp_pb->addMode(ModeNormal, "Sin", i18n("Sine"));
+ tmp_pb->addMode(ModeInverse, "Asin", i18n("Arc sine"));
+ tmp_pb->addMode(ModeHyperbolic, "Sinh", i18n("Hyperbolic sine"));
+ tmp_pb->addMode(ButtonModeFlags(ModeInverse | ModeHyperbolic),
+ "Asinh", i18n("Inverse hyperbolic sine"));
+ tmp_pb->setAccel(Key_S);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotSinclicked(void)));
+
+ tmp_pb = new KCalcButton(parent, "Cos-Button");
+ pbScientific.insert("Cosine", tmp_pb);
+ tmp_pb->addMode(ModeNormal, "Cos", i18n("Cosine"));
+ tmp_pb->addMode(ModeInverse, "Acos", i18n("Arc cosine"));
+ tmp_pb->addMode(ModeHyperbolic, "Cosh", i18n("Hyperbolic cosine"));
+ tmp_pb->addMode(ButtonModeFlags(ModeInverse | ModeHyperbolic),
+ "Acosh", i18n("Inverse hyperbolic cosine"));
+ tmp_pb->setAccel(Key_C);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotCosclicked(void)));
+
+ tmp_pb = new KCalcButton(parent, "Tan-Button");
+ pbScientific.insert("Tangent", tmp_pb);
+ tmp_pb->addMode(ModeNormal, "Tan", i18n("Tangent"));
+ tmp_pb->addMode(ModeInverse, "Atan", i18n("Arc tangent"));
+ tmp_pb->addMode(ModeHyperbolic, "Tanh", i18n("Hyperbolic tangent"));
+ tmp_pb->addMode(ButtonModeFlags(ModeInverse | ModeHyperbolic),
+ "Atanh", i18n("Inverse hyperbolic tangent"));
+ tmp_pb->setAccel(Key_T);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)),SLOT(slotTanclicked(void)));
+
+ tmp_pb = new KCalcButton(parent, "Ln-Button");
+ tmp_pb->addMode(ModeNormal, "Ln", i18n("Natural log"));
+ tmp_pb->addMode(ModeInverse, "e<sup> x </sup>", i18n("Exponential function"),
+ true);
+ pbScientific.insert("LogNatural", tmp_pb);
+ tmp_pb->setAccel(Key_N);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotLnclicked(void)));
+
+ tmp_pb = new KCalcButton(parent, "Log-Button");
+ tmp_pb->addMode(ModeNormal, "Log", i18n("Logarithm to base 10"));
+ tmp_pb->addMode(ModeInverse, "10<sup> x </sup>", i18n("10 to the power of x"),
+ true);
+ pbScientific.insert("Log10", tmp_pb);
+ tmp_pb->setAccel(Key_L);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotLogclicked(void)));
+
+}
+
+void KCalculator::setupStatisticKeys(QWidget *parent)
+{
+ Q_CHECK_PTR(parent);
+
+ KCalcButton *tmp_pb;
+
+ tmp_pb = new KCalcButton(parent, "Stat.NumData-Button");
+ tmp_pb->addMode(ModeNormal, "N", i18n("Number of data entered"));
+ tmp_pb->addMode(ModeInverse, QString::fromUtf8("\xce\xa3")
+ + "x", i18n("Sum of all data items"));
+ pbStat.insert("NumData", tmp_pb);
+ mStatButtonList.append(tmp_pb);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotStatNumclicked(void)));
+
+ tmp_pb = new KCalcButton(parent, "Stat.Median-Button");
+ tmp_pb->addMode(ModeNormal, "Med", i18n("Median"));
+ pbStat.insert("Median", tmp_pb);
+ mStatButtonList.append(tmp_pb);
+ QToolTip::add(tmp_pb, i18n("Median"));
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotStatMedianclicked(void)));
+
+ tmp_pb = new KCalcButton(parent, "Stat.Mean-Button");
+ tmp_pb->addMode(ModeNormal, "Mea", i18n("Mean"));
+ tmp_pb->addMode(ModeInverse, QString::fromUtf8("\xce\xa3")
+ + "x<sup>2</sup>",
+ i18n("Sum of all data items squared"), true);
+ pbStat.insert("Mean", tmp_pb);
+ mStatButtonList.append(tmp_pb);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotStatMeanclicked(void)));
+
+ tmp_pb = new KCalcButton(parent, "Stat.StandardDeviation-Button");
+ tmp_pb->addMode(ModeNormal, QString::fromUtf8("σ",-1) + "<sub>N-1</sub>",
+ i18n("Sample standard deviation"), true);
+ tmp_pb->addMode(ModeInverse, QString::fromUtf8("σ",-1) + "<sub>N</sub>",
+ i18n("Standard deviation"), true);
+ pbStat.insert("StandardDeviation", tmp_pb);
+ mStatButtonList.append(tmp_pb);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotStatStdDevclicked(void)));
+
+ tmp_pb = new KCalcButton(parent, "Stat.DataInput-Button");
+ tmp_pb->addMode(ModeNormal, "Dat", i18n("Enter data"));
+ tmp_pb->addMode(ModeInverse, "CDat", i18n("Delete last data item"));
+ pbStat.insert("InputData", tmp_pb);
+ mStatButtonList.append(tmp_pb);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotStatDataInputclicked(void)));
+
+ tmp_pb = new KCalcButton(parent, "Stat.ClearData-Button");
+ tmp_pb->addMode(ModeNormal, "CSt", i18n("Clear data store"));
+ pbStat.insert("ClearData", tmp_pb);
+ mStatButtonList.append(tmp_pb);
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(tmp_pb, SIGNAL(clicked(void)), SLOT(slotStatClearDataclicked(void)));
+}
+
+void KCalculator::setupConstantsKeys(QWidget *parent)
+{
+ Q_CHECK_PTR(parent);
+
+ ConstButtonGroup = new QButtonGroup(0, "Const-Button-Group");
+ connect(ConstButtonGroup, SIGNAL(clicked(int)), SLOT(slotConstclicked(int)));
+
+
+ KCalcConstButton *tmp_pb;
+ tmp_pb = new KCalcConstButton(parent, 0, "C1");
+ tmp_pb->setAccel(ALT + Key_1);
+ pbConstant[0] = tmp_pb;
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ ConstButtonGroup->insert(tmp_pb, 0);
+
+ tmp_pb = new KCalcConstButton(parent, 1, "C2");
+ tmp_pb->setAccel(ALT + Key_2);
+ pbConstant[1] = tmp_pb;
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ ConstButtonGroup->insert(tmp_pb, 1);
+
+ tmp_pb = new KCalcConstButton(parent, 2, "C3");
+ tmp_pb->setAccel(ALT + Key_3);
+ pbConstant[2] = tmp_pb;
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ ConstButtonGroup->insert(tmp_pb, 2);
+
+ tmp_pb = new KCalcConstButton(parent, 3, "C4");
+ tmp_pb->setAccel(ALT + Key_4);
+ pbConstant[3] = tmp_pb;
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ ConstButtonGroup->insert(tmp_pb, 3);
+
+ tmp_pb = new KCalcConstButton(parent, 4, "C5");
+ tmp_pb->setAccel(ALT + Key_5);
+ pbConstant[4] = tmp_pb;
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ ConstButtonGroup->insert(tmp_pb, 4);
+
+ tmp_pb = new KCalcConstButton(parent, 5, "C6");
+ tmp_pb->setAccel(ALT + Key_6);
+ pbConstant[5] = tmp_pb;
+ connect(this, SIGNAL(switchShowAccels(bool)),
+ tmp_pb, SLOT(slotSetAccelDisplayMode(bool)));
+ connect(this, SIGNAL(switchMode(ButtonModeFlags,bool)),
+ tmp_pb, SLOT(slotSetMode(ButtonModeFlags,bool)));
+ ConstButtonGroup->insert(tmp_pb, 5);
+
+ changeButtonNames();
+
+ // add menu with scientific constants
+ KCalcConstMenu *tmp_menu = new KCalcConstMenu(this);
+ menuBar()->insertItem(i18n("&Constants"), tmp_menu, -1, 2);
+ connect(tmp_menu, SIGNAL(activated(int)), this,
+ SLOT(slotConstantToDisplay(int)));
+}
+
+void KCalculator::slotConstantToDisplay(int constant)
+{
+ calc_display->setAmount(KCalcConstMenu::Constants[constant].value);
+
+ UpdateDisplay(false);
+}
+
+void KCalculator::updateGeometry(void)
+{
+ QObjectList *l;
+ QSize s;
+ int margin;
+
+ //
+ // Calculator buttons
+ //
+ s.setWidth(mSmallPage->fontMetrics().width("MMMM"));
+ s.setHeight(mSmallPage->fontMetrics().lineSpacing());
+
+ // why this stupid cast!
+ l = const_cast<QObjectList *>(mSmallPage->children());
+
+ for(uint i=0; i < l->count(); i++)
+ {
+ QObject *o = l->at(i);
+ if( o->isWidgetType() )
+ {
+ QWidget *tmp_widget = dynamic_cast<QWidget *>(o);
+ margin = QApplication::style().
+ pixelMetric(QStyle::PM_ButtonMargin, (tmp_widget))*2;
+ tmp_widget->setFixedSize(s.width()+margin, s.height()+margin);
+ //tmp_widget->setMinimumSize(s.width()+margin, s.height()+margin);
+ tmp_widget->installEventFilter( this );
+ tmp_widget->setAcceptDrops(true);
+ }
+ }
+
+ // why this stupic cast !!
+ l = const_cast<QObjectList*>(mLargePage->children());
+
+ int h1 = (NumButtonGroup->find(0x0F))->minimumSize().height();
+ int h2 = static_cast<int>( (static_cast<float>(h1) + 4.0) / 5.0 );
+ s.setWidth(mLargePage->fontMetrics().width("MMM") +
+ QApplication::style().
+ pixelMetric(QStyle::PM_ButtonMargin, NumButtonGroup->find(0x0F))*2);
+ s.setHeight(h1 + h2);
+
+ for(uint i = 0; i < l->count(); i++)
+ {
+ QObject *o = l->at(i);
+ if(o->isWidgetType())
+ {
+ QWidget *tmp_widget = dynamic_cast<QWidget *>(o);
+ tmp_widget->setFixedSize(s);
+ tmp_widget->installEventFilter(this);
+ tmp_widget->setAcceptDrops(true);
+ }
+ }
+
+ pbInv->setFixedSize(s);
+ pbInv->installEventFilter(this);
+ pbInv->setAcceptDrops(true);
+
+
+
+ l = (QObjectList*)mNumericPage->children(); // silence please
+
+ h1 = (NumButtonGroup->find(0x0F))->minimumSize().height();
+ h2 = (int)((((float)h1 + 4.0) / 5.0));
+ s.setWidth(mLargePage->fontMetrics().width("MMM") +
+ QApplication::style().
+ pixelMetric(QStyle::PM_ButtonMargin, NumButtonGroup->find(0x0F))*2);
+ s.setHeight(h1 + h2);
+
+ for(uint i = 0; i < l->count(); i++)
+ {
+ QObject *o = l->at(i);
+ if(o->isWidgetType())
+ {
+ QWidget *tmp_widget = dynamic_cast<QWidget *>(o);
+ tmp_widget->setFixedSize(s);
+ tmp_widget->installEventFilter(this);
+ tmp_widget->setAcceptDrops(true);
+ }
+ }
+
+ // Set Buttons of double size
+ QSize t(s);
+ t.setWidth(2*s.width());
+ NumButtonGroup->find(0x00)->setFixedSize(t);
+ t = s;
+ t.setHeight(2*s.height());
+ pbEqual->setFixedSize(t);
+ pbPlus->setFixedSize(t);
+}
+
+void KCalculator::slotBaseSelected(int base)
+{
+ int current_base;
+
+ // set display & statusbar (if item exist in statusbar)
+ switch(base)
+ {
+ case 3:
+ current_base = calc_display->setBase(NumBase(2));
+ if (statusBar()->hasItem(1)) statusBar()->changeItem("BIN",1);
+ calc_display->setStatusText(1, "Bin");
+ break;
+ case 2:
+ current_base = calc_display->setBase(NumBase(8));
+ if (statusBar()->hasItem(1)) statusBar()->changeItem("OCT",1);
+ calc_display->setStatusText(1, "Oct");
+ break;
+ case 1:
+ current_base = calc_display->setBase(NumBase(10));
+ if (statusBar()->hasItem(1)) statusBar()->changeItem("DEC",1);
+ calc_display->setStatusText(1, "Dec");
+ break;
+ case 0:
+ current_base = calc_display->setBase(NumBase(16));
+ if (statusBar()->hasItem(1)) statusBar()->changeItem("HEX",1);
+ calc_display->setStatusText(1, "Hex");
+ break;
+ default:
+ if (statusBar()->hasItem(1)) statusBar()->changeItem("Error",1);
+ calc_display->setStatusText(1, "Error");
+ return;
+ }
+
+ // Enable the buttons not available in this base
+ for (int i=0; i<current_base; i++)
+ NumButtonGroup->find(i)->setEnabled (true);
+
+ // Disable the buttons not available in this base
+ for (int i=current_base; i<16; i++)
+ NumButtonGroup->find(i)->setEnabled (false);
+
+ // Only enable the decimal point in decimal
+ pbPeriod->setEnabled(current_base == NB_DECIMAL);
+ // Only enable the x*10^y button in decimal
+ pbEE->setEnabled(current_base == NB_DECIMAL);
+
+ // Disable buttons that make only sense with floating point
+ // numbers
+ if(current_base != NB_DECIMAL)
+ {
+ pbScientific["HypMode"]->setEnabled(false);
+ pbScientific["Sine"]->setEnabled(false);
+ pbScientific["Cosine"]->setEnabled(false);
+ pbScientific["Tangent"]->setEnabled(false);
+ pbScientific["LogNatural"]->setEnabled(false);
+ pbScientific["Log10"]->setEnabled(false);
+ }
+ else
+ {
+ pbScientific["HypMode"]->setEnabled(true);
+ pbScientific["Sine"]->setEnabled(true);
+ pbScientific["Cosine"]->setEnabled(true);
+ pbScientific["Tangent"]->setEnabled(true);
+ pbScientific["LogNatural"]->setEnabled(true);
+ pbScientific["Log10"]->setEnabled(true);
+ }
+}
+
+void KCalculator::keyPressEvent(QKeyEvent *e)
+{
+ if ( ( e->state() & KeyButtonMask ) == 0 || ( e->state() & ShiftButton ) ) {
+ switch (e->key())
+ {
+ case Key_Next:
+ pbAC->animateClick();
+ break;
+ case Key_Slash:
+ case Key_division:
+ pbDivision->animateClick();
+ break;
+ case Key_D:
+ pbStat["InputData"]->animateClick(); // stat mode
+ break;
+ case Key_BracketLeft:
+ case Key_twosuperior:
+ pbSquare->animateClick();
+ break;
+ case Key_Backspace:
+ calc_display->deleteLastDigit();
+ // pbAC->animateClick();
+ break;
+ }
+ }
+
+ if (e->key() == Key_Control)
+ emit switchShowAccels(true);
+}
+
+void KCalculator::keyReleaseEvent(QKeyEvent *e)
+{
+ if (e->key() == Key_Control)
+ emit switchShowAccels(false);
+}
+
+void KCalculator::slotAngleSelected(int number)
+{
+ pbAngleChoose->popup()->setItemChecked(0, false);
+ pbAngleChoose->popup()->setItemChecked(1, false);
+ pbAngleChoose->popup()->setItemChecked(2, false);
+
+ switch(number)
+ {
+ case 0:
+ _angle_mode = DegMode;
+ statusBar()->changeItem("DEG", 2);
+ pbAngleChoose->popup()->setItemChecked(0, true);
+ calc_display->setStatusText(2, "Deg");
+ break;
+ case 1:
+ _angle_mode = RadMode;
+ statusBar()->changeItem("RAD", 2);
+ pbAngleChoose->popup()->setItemChecked(1, true);
+ calc_display->setStatusText(2, "Rad");
+ break;
+ case 2:
+ _angle_mode = GradMode;
+ statusBar()->changeItem("GRA", 2);
+ pbAngleChoose->popup()->setItemChecked(2, true);
+ calc_display->setStatusText(2, "Gra");
+ break;
+ default: // we shouldn't ever end up here
+ _angle_mode = RadMode;
+ }
+}
+
+void KCalculator::slotEEclicked(void)
+{
+ calc_display->newCharacter('e');
+}
+
+void KCalculator::slotInvtoggled(bool flag)
+{
+ inverse = flag;
+
+ emit switchMode(ModeInverse, flag);
+
+ if (inverse)
+ {
+ statusBar()->changeItem("INV", 0);
+ calc_display->setStatusText(0, "Inv");
+ }
+ else
+ {
+ statusBar()->changeItem("NORM", 0);
+ calc_display->setStatusText(0, QString::null);
+ }
+}
+
+void KCalculator::slotHyptoggled(bool flag)
+{
+ // toggle between hyperbolic and standart trig functions
+ hyp_mode = flag;
+
+ emit switchMode(ModeHyperbolic, flag);
+}
+
+
+
+void KCalculator::slotMemRecallclicked(void)
+{
+ // temp. work-around
+ calc_display->sendEvent(KCalcDisplay::EventReset);
+
+ calc_display->setAmount(memory_num);
+ UpdateDisplay(false);
+}
+
+void KCalculator::slotMemStoreclicked(void)
+{
+ EnterEqual();
+
+ memory_num = calc_display->getAmount();
+ calc_display->setStatusText(3, "M");
+ statusBar()->changeItem("M",3);
+ pbMemRecall->setEnabled(true);
+}
+
+void KCalculator::slotNumberclicked(int number_clicked)
+{
+ calc_display->EnterDigit(number_clicked);
+}
+
+void KCalculator::slotSinclicked(void)
+{
+ if (hyp_mode)
+ {
+ // sinh or arsinh
+ if (!inverse)
+ core.SinHyp(calc_display->getAmount());
+ else
+ core.AreaSinHyp(calc_display->getAmount());
+ }
+ else
+ {
+ // sine or arcsine
+ if (!inverse)
+ switch(_angle_mode)
+ {
+ case DegMode:
+ core.SinDeg(calc_display->getAmount());
+ break;
+ case RadMode:
+ core.SinRad(calc_display->getAmount());
+ break;
+ case GradMode:
+ core.SinGrad(calc_display->getAmount());
+ break;
+ }
+ else
+ switch(_angle_mode)
+ {
+ case DegMode:
+ core.ArcSinDeg(calc_display->getAmount());
+ break;
+ case RadMode:
+ core.ArcSinRad(calc_display->getAmount());
+ break;
+ case GradMode:
+ core.ArcSinGrad(calc_display->getAmount());
+ break;
+ }
+ }
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotPlusMinusclicked(void)
+{
+ // display can only change sign, when in input mode, otherwise we
+ // need the core to do this.
+ if (!calc_display->sendEvent(KCalcDisplay::EventChangeSign))
+ {
+ core.InvertSign(calc_display->getAmount());
+ UpdateDisplay(true);
+ }
+}
+
+void KCalculator::slotMemPlusMinusclicked(void)
+{
+ bool tmp_inverse = inverse; // store this, because next command deletes inverse
+ EnterEqual(); // finish calculation so far, to store result into MEM
+
+ if (!tmp_inverse) memory_num += calc_display->getAmount();
+ else memory_num -= calc_display->getAmount();
+
+ pbInv->setOn(false);
+ statusBar()->changeItem("M",3);
+ calc_display->setStatusText(3, "M");
+ pbMemRecall->setEnabled(true);
+}
+
+void KCalculator::slotCosclicked(void)
+{
+ if (hyp_mode)
+ {
+ // cosh or arcosh
+ if (!inverse)
+ core.CosHyp(calc_display->getAmount());
+ else
+ core.AreaCosHyp(calc_display->getAmount());
+ }
+ else
+ {
+ // cosine or arccosine
+ if (!inverse)
+ switch(_angle_mode)
+ {
+ case DegMode:
+ core.CosDeg(calc_display->getAmount());
+ break;
+ case RadMode:
+ core.CosRad(calc_display->getAmount());
+ break;
+ case GradMode:
+ core.CosGrad(calc_display->getAmount());
+ break;
+ }
+ else
+ switch(_angle_mode)
+ {
+ case DegMode:
+ core.ArcCosDeg(calc_display->getAmount());
+ break;
+ case RadMode:
+ core.ArcCosRad(calc_display->getAmount());
+ break;
+ case GradMode:
+ core.ArcCosGrad(calc_display->getAmount());
+ break;
+ }
+ }
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotReciclicked(void)
+{
+ core.Reciprocal(calc_display->getAmount());
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotTanclicked(void)
+{
+ if (hyp_mode)
+ {
+ // tanh or artanh
+ if (!inverse)
+ core.TangensHyp(calc_display->getAmount());
+ else
+ core.AreaTangensHyp(calc_display->getAmount());
+ }
+ else
+ {
+ // tan or arctan
+ if (!inverse)
+ switch(_angle_mode)
+ {
+ case DegMode:
+ core.TangensDeg(calc_display->getAmount());
+ break;
+ case RadMode:
+ core.TangensRad(calc_display->getAmount());
+ break;
+ case GradMode:
+ core.TangensGrad(calc_display->getAmount());
+ break;
+ }
+ else
+ switch(_angle_mode)
+ {
+ case DegMode:
+ core.ArcTangensDeg(calc_display->getAmount());
+ break;
+ case RadMode:
+ core.ArcTangensRad(calc_display->getAmount());
+ break;
+ case GradMode:
+ core.ArcTangensGrad(calc_display->getAmount());
+ break;
+ }
+ }
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotFactorialclicked(void)
+{
+ core.Factorial(calc_display->getAmount());
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotLogclicked(void)
+{
+ if (!inverse)
+ core.Log10(calc_display->getAmount());
+ else
+ core.Exp10(calc_display->getAmount());
+
+ UpdateDisplay(true);
+}
+
+
+void KCalculator::slotSquareclicked(void)
+{
+ if (!inverse)
+ core.Square(calc_display->getAmount());
+ else
+ core.Cube(calc_display->getAmount());
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotRootclicked(void)
+{
+ if (!inverse)
+ core.SquareRoot(calc_display->getAmount());
+ else
+ core.CubeRoot(calc_display->getAmount());
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotLnclicked(void)
+{
+ if (!inverse)
+ core.Ln(calc_display->getAmount());
+ else
+ core.Exp(calc_display->getAmount());
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotPowerclicked(void)
+{
+ if (inverse)
+ {
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_PWR_ROOT);
+ pbInv->setOn(false);
+ }
+ else
+ {
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_POWER);
+ }
+ // temp. work-around
+ KNumber tmp_num = calc_display->getAmount();
+ calc_display->sendEvent(KCalcDisplay::EventReset);
+ calc_display->setAmount(tmp_num);
+ UpdateDisplay(false);
+}
+
+void KCalculator::slotMCclicked(void)
+{
+ memory_num = 0;
+ statusBar()->changeItem(" \xa0\xa0 ",3);
+ calc_display->setStatusText(3, QString::null);
+ pbMemRecall->setDisabled(true);
+}
+
+void KCalculator::slotClearclicked(void)
+{
+ calc_display->sendEvent(KCalcDisplay::EventClear);
+}
+
+void KCalculator::slotACclicked(void)
+{
+ core.Reset();
+ calc_display->sendEvent(KCalcDisplay::EventReset);
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotParenOpenclicked(void)
+{
+ core.ParenOpen(calc_display->getAmount());
+
+ // What behavior, if e.g.: "12(6*6)"??
+ //UpdateDisplay(true);
+}
+
+void KCalculator::slotParenCloseclicked(void)
+{
+ core.ParenClose(calc_display->getAmount());
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotANDclicked(void)
+{
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_AND);
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotXclicked(void)
+{
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_MULTIPLY);
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotDivisionclicked(void)
+{
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_DIVIDE);
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotORclicked(void)
+{
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_OR);
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotXORclicked(void)
+{
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_XOR);
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotPlusclicked(void)
+{
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_ADD);
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotMinusclicked(void)
+{
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_SUBTRACT);
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotLeftShiftclicked(void)
+{
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_LSH);
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotRightShiftclicked(void)
+{
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_RSH);
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotPeriodclicked(void)
+{
+ calc_display->newCharacter('.');
+}
+
+void KCalculator::EnterEqual()
+{
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_EQUAL);
+
+ UpdateDisplay(true, true);
+}
+
+void KCalculator::slotEqualclicked(void)
+{
+ EnterEqual();
+}
+
+void KCalculator::slotPercentclicked(void)
+{
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_PERCENT);
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotNegateclicked(void)
+{
+ core.Complement(calc_display->getAmount());
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotModclicked(void)
+{
+ if (inverse)
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_INTDIV);
+ else
+ core.enterOperation(calc_display->getAmount(),
+ CalcEngine::FUNC_MOD);
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotStatNumclicked(void)
+{
+ if(!inverse)
+ {
+ core.StatCount(0);
+ }
+ else
+ {
+ pbInv->setOn(false);
+ core.StatSum(0);
+ }
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotStatMeanclicked(void)
+{
+ if(!inverse)
+ core.StatMean(0);
+ else
+ {
+ pbInv->setOn(false);
+ core.StatSumSquares(0);
+ }
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotStatStdDevclicked(void)
+{
+ if(inverse)
+ {
+ // std (n-1)
+ core.StatStdDeviation(0);
+ pbInv->setOn(false);
+ }
+ else
+ {
+ // std (n)
+ core.StatStdSample(0);
+ }
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotStatMedianclicked(void)
+{
+ if(!inverse)
+ {
+ // std (n-1)
+ core.StatMedian(0);
+ }
+ else
+ {
+ // std (n)
+ core.StatMedian(0);
+ pbInv->setOn(false);
+ }
+ // it seems two different modes should be implemented, but...?
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotStatDataInputclicked(void)
+{
+ if(!inverse)
+ {
+ core.StatDataNew(calc_display->getAmount());
+ }
+ else
+ {
+ pbInv->setOn(false);
+ core.StatDataDel(0);
+ statusBar()->message(i18n("Last stat item erased"), 3000);
+ }
+
+ UpdateDisplay(true);
+}
+
+void KCalculator::slotStatClearDataclicked(void)
+{
+ if(!inverse)
+ {
+ core.StatClearAll(0);
+ statusBar()->message(i18n("Stat mem cleared"), 3000);
+ }
+ else
+ {
+ pbInv->setOn(false);
+ UpdateDisplay(false);
+ }
+}
+
+void KCalculator::slotConstclicked(int button)
+{
+ if(!inverse)
+ {
+ //set the display to the configured value of Constant Button
+ calc_display->setAmount(pbConstant[button]->constant());
+ }
+ else
+ {
+ pbInv->setOn(false);
+ KCalcSettings::setValueConstant(button, calc_display->text());
+ // below set new tooltip
+ pbConstant[button]->setLabelAndTooltip();
+ // work around: after storing a number, pressing a digit should start
+ // a new number
+ calc_display->setAmount(calc_display->getAmount());
+ }
+
+ UpdateDisplay(false);
+}
+
+void KCalculator::showSettings()
+{
+ // Check if there is already a dialog and if so bring
+ // it to the foreground.
+ if(KConfigDialog::showDialog("settings"))
+ return;
+
+ // Create a new dialog with the same name as the above checking code.
+ KConfigDialog *dialog = new KConfigDialog(this, "settings", KCalcSettings::self());
+ dialog->enableButtonSeparator( true );
+
+ // Add the general page. Store the settings in the General group and
+ // use the icon package_settings.
+ General *general = new General(0, "General");
+ int maxprec = 1000;
+ general->kcfg_Precision->setMaxValue(maxprec);
+ dialog->addPage(general, i18n("General"), "package_settings", i18n("General Settings"));
+
+ QWidget *fontWidget = new QWidget(0,"Font");
+ QVBoxLayout *fontLayout = new QVBoxLayout(fontWidget);
+ KFontChooser *mFontChooser =
+ new KFontChooser(fontWidget, "kcfg_Font", false, QStringList(), false, 6);
+
+ fontLayout->addWidget(mFontChooser);
+ dialog->addPage(fontWidget, i18n("Font"), "fonts", i18n("Select Display Font"));
+
+ // color settings
+
+ Colors *color = new Colors(0, "Color");
+
+ dialog->addPage(color, i18n("Colors"), "colors", i18n("Button & Display Colors"));
+
+ // constant settings
+
+ Constants *constant = new Constants(0, "Constant" );
+ tmp_const = constant;
+
+ KCalcConstMenu *tmp_menu = new KCalcConstMenu(this);
+ connect(tmp_menu, SIGNAL(activated(int)),
+ SLOT(slotChooseScientificConst0(int)));
+ (constant->kPushButton0)->setPopup(tmp_menu);
+
+ tmp_menu = new KCalcConstMenu(this);
+ connect(tmp_menu, SIGNAL(activated(int)),
+ SLOT(slotChooseScientificConst1(int)));
+ (constant->kPushButton1)->setPopup(tmp_menu);
+
+ tmp_menu = new KCalcConstMenu(this);
+ connect(tmp_menu, SIGNAL(activated(int)),
+ SLOT(slotChooseScientificConst2(int)));
+ (constant->kPushButton2)->setPopup(tmp_menu);
+
+ tmp_menu = new KCalcConstMenu(this);
+ connect(tmp_menu, SIGNAL(activated(int)),
+ SLOT(slotChooseScientificConst3(int)));
+ (constant->kPushButton3)->setPopup(tmp_menu);
+
+ tmp_menu = new KCalcConstMenu(this);
+ connect(tmp_menu, SIGNAL(activated(int)),
+ SLOT(slotChooseScientificConst4(int)));
+ (constant->kPushButton4)->setPopup(tmp_menu);
+
+ tmp_menu = new KCalcConstMenu(this);
+ connect(tmp_menu, SIGNAL(activated(int)),
+ SLOT(slotChooseScientificConst5(int)));
+ (constant->kPushButton5)->setPopup(tmp_menu);
+
+ dialog->addPage(constant, i18n("Constants"), "constants");
+
+
+ // When the user clicks OK or Apply we want to update our settings.
+ connect(dialog, SIGNAL(settingsChanged()), SLOT(updateSettings()));
+
+ // Display the dialog.
+ dialog->show();
+}
+
+
+// these 6 slots are just a quick hack, instead of setting the
+// TextEdit fields in the configuration dialog, we are setting the
+// Settingvalues themselves!!
+void KCalculator::slotChooseScientificConst0(int option)
+{
+ (tmp_const->kcfg_valueConstant0)->setText(KCalcConstMenu::Constants[option].value);
+
+ (tmp_const->kcfg_nameConstant0)->setText(KCalcConstMenu::Constants[option].label);
+}
+
+void KCalculator::slotChooseScientificConst1(int option)
+{
+ (tmp_const->kcfg_valueConstant1)->setText(KCalcConstMenu::Constants[option].value);
+
+ (tmp_const->kcfg_nameConstant1)->setText(KCalcConstMenu::Constants[option].label);
+}
+
+void KCalculator::slotChooseScientificConst2(int option)
+{
+ (tmp_const->kcfg_valueConstant2)->setText(KCalcConstMenu::Constants[option].value);
+
+ (tmp_const->kcfg_nameConstant2)->setText(KCalcConstMenu::Constants[option].label);
+}
+
+void KCalculator::slotChooseScientificConst3(int option)
+{
+ (tmp_const->kcfg_valueConstant3)->setText(KCalcConstMenu::Constants[option].value);
+
+ (tmp_const->kcfg_nameConstant3)->setText(KCalcConstMenu::Constants[option].label);
+}
+
+void KCalculator::slotChooseScientificConst4(int option)
+{
+ (tmp_const->kcfg_valueConstant4)->setText(KCalcConstMenu::Constants[option].value);
+
+ (tmp_const->kcfg_nameConstant4)->setText(KCalcConstMenu::Constants[option].label);
+}
+
+void KCalculator::slotChooseScientificConst5(int option)
+{
+ (tmp_const->kcfg_valueConstant5)->setText(KCalcConstMenu::Constants[option].value);
+
+ (tmp_const->kcfg_nameConstant5)->setText(KCalcConstMenu::Constants[option].label);
+}
+
+
+void KCalculator::slotStatshow(bool toggled)
+{
+ if(toggled)
+ {
+ pbStat["NumData"]->show();
+ pbStat["Mean"]->show();
+ pbStat["StandardDeviation"]->show();
+ pbStat["Median"]->show();
+ pbStat["InputData"]->show();
+ pbStat["ClearData"]->show();
+ }
+ else
+ {
+ pbStat["NumData"]->hide();
+ pbStat["Mean"]->hide();
+ pbStat["StandardDeviation"]->hide();
+ pbStat["Median"]->hide();
+ pbStat["InputData"]->hide();
+ pbStat["ClearData"]->hide();
+ }
+ adjustSize();
+ setFixedSize(sizeHint());
+ KCalcSettings::setShowStat(toggled);
+}
+
+void KCalculator::slotScientificshow(bool toggled)
+{
+ if(toggled)
+ {
+ pbScientific["HypMode"]->show();
+ pbScientific["Sine"]->show();
+ pbScientific["Cosine"]->show();
+ pbScientific["Tangent"]->show();
+ pbScientific["Log10"]->show();
+ pbScientific["LogNatural"]->show();
+ pbAngleChoose->show();
+ if(!statusBar()->hasItem(2))
+ statusBar()->insertFixedItem(" DEG ", 2, true);
+ statusBar()->setItemAlignment(2, AlignCenter);
+ calc_display->setStatusText(2, "Deg");
+ slotAngleSelected(0);
+ }
+ else
+ {
+ pbScientific["HypMode"]->hide();
+ pbScientific["Sine"]->hide();
+ pbScientific["Cosine"]->hide();
+ pbScientific["Tangent"]->hide();
+ pbScientific["Log10"]->hide();
+ pbScientific["LogNatural"]->hide();
+ pbAngleChoose->hide();
+ if(statusBar()->hasItem(2))
+ statusBar()->removeItem(2);
+ calc_display->setStatusText(2, QString::null);
+ }
+ adjustSize();
+ setFixedSize(sizeHint());
+ KCalcSettings::setShowScientific(toggled);
+}
+
+void KCalculator::slotLogicshow(bool toggled)
+{
+ if(toggled)
+ {
+ pbLogic["AND"]->show();
+ pbLogic["OR"]->show();
+ pbLogic["XOR"]->show();
+ pbLogic["One-Complement"]->show();
+ pbLogic["LeftShift"]->show();
+ pbLogic["RightShift"]->show();
+ if(!statusBar()->hasItem(1))
+ statusBar()->insertFixedItem(" HEX ", 1, true);
+ statusBar()->setItemAlignment(1, AlignCenter);
+ calc_display->setStatusText(1, "Hex");
+ resetBase();
+ BaseChooseGroup->show();
+ for (int i=10; i<16; i++)
+ (NumButtonGroup->find(i))->show();
+ }
+ else
+ {
+ pbLogic["AND"]->hide();
+ pbLogic["OR"]->hide();
+ pbLogic["XOR"]->hide();
+ pbLogic["One-Complement"]->hide();
+ pbLogic["LeftShift"]->hide();
+ pbLogic["RightShift"]->hide();
+ // Hide Hex-Buttons, but first switch back to decimal
+ resetBase();
+ BaseChooseGroup->hide();
+ if(statusBar()->hasItem(1))
+ statusBar()->removeItem(1);
+ calc_display->setStatusText(1, QString::null);
+ for (int i=10; i<16; i++)
+ (NumButtonGroup->find(i))->hide();
+ }
+ adjustSize();
+ setFixedSize(sizeHint());
+ KCalcSettings::setShowLogic(toggled);
+}
+
+void KCalculator::slotConstantsShow(bool toggled)
+{
+ if(toggled)
+ {
+ pbConstant[0]->show();
+ pbConstant[1]->show();
+ pbConstant[2]->show();
+ pbConstant[3]->show();
+ pbConstant[4]->show();
+ pbConstant[5]->show();
+
+ }
+ else
+ {
+ pbConstant[0]->hide();
+ pbConstant[1]->hide();
+ pbConstant[2]->hide();
+ pbConstant[3]->hide();
+ pbConstant[4]->hide();
+ pbConstant[5]->hide();
+ }
+ adjustSize();
+ setFixedSize(sizeHint());
+ KCalcSettings::setShowConstants(toggled);
+}
+
+// This function is for setting the constant names configured in the
+// kcalc settings menu. If the user doesn't enter a name for the
+// constant C1 to C6 is used.
+void KCalculator::changeButtonNames()
+{
+ pbConstant[0]->setLabelAndTooltip();
+ pbConstant[1]->setLabelAndTooltip();
+ pbConstant[2]->setLabelAndTooltip();
+ pbConstant[3]->setLabelAndTooltip();
+ pbConstant[4]->setLabelAndTooltip();
+ pbConstant[5]->setLabelAndTooltip();
+}
+
+void KCalculator::slotShowAll(void)
+{
+ // I wonder why "setChecked" does not emit "toggled"
+ if(!actionStatshow->isChecked()) actionStatshow->activate();
+ if(!actionScientificshow->isChecked()) actionScientificshow->activate();
+ if(!actionLogicshow->isChecked()) actionLogicshow->activate();
+ if(!actionConstantsShow->isChecked()) actionConstantsShow->activate();
+}
+
+void KCalculator::slotHideAll(void)
+{
+ // I wonder why "setChecked" does not emit "toggled"
+ if(actionStatshow->isChecked()) actionStatshow->activate();
+ if(actionScientificshow->isChecked()) actionScientificshow->activate();
+ if(actionLogicshow->isChecked()) actionLogicshow->activate();
+ if(actionConstantsShow->isChecked()) actionConstantsShow->activate();
+}
+
+void KCalculator::updateSettings()
+{
+ changeButtonNames();
+ set_colors();
+ set_precision();
+ // Show the result in the app's caption in taskbar (wishlist - bug #52858)
+ disconnect(calc_display, SIGNAL(changedText(const QString &)),
+ this, 0);
+ if (KCalcSettings::captionResult())
+ {
+ connect(calc_display,
+ SIGNAL(changedText(const QString &)),
+ SLOT(setCaption(const QString &)));
+ }
+ else
+ {
+ setCaption(QString::null);
+ }
+ calc_display->changeSettings();
+
+ updateGeometry();
+ resize(minimumSize());
+
+ //
+ // 1999-10-31 Espen Sand: Don't ask me why ;)
+ //
+ kapp->processOneEvent();
+ setFixedHeight(minimumHeight());
+}
+
+void KCalculator::UpdateDisplay(bool get_amount_from_core,
+ bool store_result_in_history)
+{
+ if(get_amount_from_core)
+ {
+ calc_display->update_from_core(core, store_result_in_history);
+ }
+ else
+ {
+ calc_display->update();
+ }
+
+ pbInv->setOn(false);
+
+}
+
+void KCalculator::set_colors()
+{
+ QPushButton *p = NULL;
+
+ calc_display->changeSettings();
+
+ QColor bg = palette().active().background();
+
+ QPalette numPal(KCalcSettings::numberButtonsColor(), bg);
+ for(int i=0; i<10; i++)
+ {
+ (NumButtonGroup->find(i))->setPalette(numPal);
+ }
+
+ QPalette funcPal(KCalcSettings::functionButtonsColor(), bg);
+ for(p = mFunctionButtonList.first(); p;
+ p=mFunctionButtonList.next())
+ {
+ p->setPalette(funcPal);
+ }
+
+ QPalette statPal(KCalcSettings::statButtonsColor(), bg);
+ for(p = mStatButtonList.first(); p; p=mStatButtonList.next())
+ {
+ p->setPalette(statPal);
+ }
+
+ QPalette hexPal(KCalcSettings::hexButtonsColor(), bg);
+ for(int i=10; i<16; i++)
+ {
+ (NumButtonGroup->find(i))->setPalette(hexPal);
+ }
+
+ QPalette memPal(KCalcSettings::memoryButtonsColor(), bg);
+ for(p = mMemButtonList.first(); p; p=mMemButtonList.next())
+ {
+ p->setPalette(memPal);
+ }
+
+ QPalette opPal(KCalcSettings::operationButtonsColor(), bg);
+ for(p = mOperationButtonList.first(); p;
+ p=mOperationButtonList.next())
+ {
+ p->setPalette(opPal);
+ }
+}
+
+void KCalculator::set_precision()
+{
+ KNumber:: setDefaultFloatPrecision(KCalcSettings::precision());
+ UpdateDisplay(false);
+}
+
+bool KCalculator::eventFilter(QObject *o, QEvent *e)
+{
+ if(e->type() == QEvent::DragEnter)
+ {
+ QDragEnterEvent *ev = (QDragEnterEvent *)e;
+ ev->accept(KColorDrag::canDecode(ev));
+ return true;
+ }
+ else if(e->type() == QEvent::DragLeave)
+ {
+ return true;
+ }
+ else if(e->type() == QEvent::Drop)
+ {
+ if(!o->isA("KCalcButton"))
+ return false;
+
+ QColor c;
+ QDropEvent *ev = (QDropEvent *)e;
+ if( KColorDrag::decode(ev, c))
+ {
+ QPtrList<KCalcButton> *list;
+ int num_but;
+ if((num_but = NumButtonGroup->id((KCalcButton*)o))
+ != -1)
+ {
+ QPalette pal(c, palette().active().background());
+
+ // Was it hex-button or normal digit??
+ if (num_but <10)
+ for(int i=0; i<10; i++)
+ (NumButtonGroup->find(i))->setPalette(pal);
+ else
+ for(int i=10; i<16; i++)
+ (NumButtonGroup->find(i))->setPalette(pal);
+
+ return true;
+ }
+ else if( mFunctionButtonList.findRef((KCalcButton*)o) != -1)
+ {
+ list = &mFunctionButtonList;
+ }
+ else if( mStatButtonList.findRef((KCalcButton*)o) != -1)
+ {
+ list = &mStatButtonList;
+ }
+ else if( mMemButtonList.findRef((KCalcButton*)o) != -1)
+ {
+ list = &mMemButtonList;
+ }
+ else if( mOperationButtonList.findRef((KCalcButton*)o) != -1)
+ {
+ list = &mOperationButtonList;
+ }
+ else
+ return false;
+
+ QPalette pal(c, palette().active().background());
+
+ for(KCalcButton *p = list->first(); p; p=list->next())
+ p->setPalette(pal);
+ }
+
+ return true;
+ }
+ else
+ {
+ return KMainWindow::eventFilter(o, e);
+ }
+}
+
+
+
+
+////////////////////////////////////////////////////////////////
+// Include the meta-object code for classes in this file
+//
+
+#include "kcalc.moc"
+
+
+extern "C" KDE_EXPORT int kdemain(int argc, char *argv[])
+{
+ KAboutData aboutData( "kcalc", I18N_NOOP("KCalc"),
+ version, description, KAboutData::License_GPL,
+ I18N_NOOP("(c) 2003-2005, Klaus Niederkr" "\xc3\xbc" "ger\n"
+ "(c) 1996-2000, Bernd Johannes Wuebben\n"
+ "(c) 2000-2005, The KDE Team"));
+
+ /* Klaus Niederkrueger */
+ aboutData.addAuthor("Klaus Niederkr" "\xc3\xbc" "ger", 0, "kniederk@math.uni-koeln.de");
+ aboutData.addAuthor("Bernd Johannes Wuebben", 0, "wuebben@kde.org");
+ aboutData.addAuthor("Evan Teran", 0, "eteran@alum.rit.edu");
+ aboutData.addAuthor("Espen Sand", 0, "espen@kde.org");
+ aboutData.addAuthor("Chris Howells", 0, "howells@kde.org");
+ aboutData.addAuthor("Aaron J. Seigo", 0, "aseigo@olympusproject.org");
+ aboutData.addAuthor("Charles Samuels", 0, "charles@altair.dhs.org");
+ /* Rene Merou */
+ aboutData.addAuthor("Ren" "\xc3\xa9" " M" "\xc3\xa9" "rou", 0, "ochominutosdearco@yahoo.es");
+ KCmdLineArgs::init(argc, argv, &aboutData);
+
+ KApplication app;
+#if 0
+ app->enableSessionManagement(true);
+ app->setWmCommand(argv[0]);
+#endif
+
+ KCalculator *calc = new KCalculator;
+ app.setTopWidget(calc);
+ calc->setCaption(QString::null);
+ calc->show();
+
+ int exitCode = app.exec();
+
+ return(exitCode);
+}
+
diff --git a/kcalc/kcalc.desktop b/kcalc/kcalc.desktop
new file mode 100644
index 0000000..19ae663
--- /dev/null
+++ b/kcalc/kcalc.desktop
@@ -0,0 +1,88 @@
+[Desktop Entry]
+Name=KCalc
+Name[af]=Kcalc
+Name[ar]=حاسب؊ ك
+Name[eo]=Kalkulilo
+Name[hi]=के-केल्क
+Name[lv]=KKalk
+Name[ne]=केडीई क्याल्क
+Name[pa]=ਕੇਹਿਸਾਬੀ
+Name[pl]=Kalkulator
+Name[sv]=Kcalc
+Name[ta]=கேகணிப்பான்
+Name[tg]=KМошинаи ҳисобкунак
+Name[th]=เครื่องคิดเลข
+Name[uz]=Kalkulyator
+Name[uz@cyrillic]=Калкулятор
+Name[zh_TW]=KDE 計算機
+Exec=kcalc -caption "%c" %i %m
+Icon=kcalc
+DocPath=kcalc/index.html
+GenericName=Scientific Calculator
+GenericName[af]=Wetenskaplike Sakrekenaar
+GenericName[ar]=آلة حاسبة علمية
+GenericName[bg]=Калкулатор
+GenericName[br]=Ur jederez skiantel
+GenericName[bs]=Znanstveni kalkulator
+GenericName[ca]=Calculadora cientĂ­fica
+GenericName[cs]=Vědecká kalkulačka
+GenericName[cy]=Cyfrifydd Gwyddonol
+GenericName[da]=Videnskabelig regnemaskine
+GenericName[de]=Wissenschaftlicher Taschenrechner
+GenericName[el]=Επιστημονικό κομπιουτεράκι
+GenericName[eo]=Scienca kalkulilo
+GenericName[es]=Calculadora cientĂ­fica
+GenericName[et]=Teaduslik kalkulaator
+GenericName[eu]=Kalkulagailu Zientifikoa
+GenericName[fa]=ماشین حساب علمی
+GenericName[fi]=Tieteellinen laskin
+GenericName[fr]=Une calculatrice scientifique
+GenericName[ga]=Áireamhån Eolaíochta
+GenericName[he]=מחשבון מדעי
+GenericName[hi]=वैज्ञानिक गणक
+GenericName[hr]=Znanstveni kalkulator
+GenericName[hu]=SzĂĄmolĂłgĂŠp
+GenericName[is]=Öflug reiknivél
+GenericName[it]=Calcolatrice scientifica
+GenericName[ja]=科学電卓
+GenericName[ka]=მეცნიერული კალკულატორი
+GenericName[kk]=Ғылыми калькулятор
+GenericName[km]=ម៉ាស៊ីន​គិត​លេខ​វិទ្យាសាស្ត្រ
+GenericName[lt]=Mokslinis skaičiuotuvas
+GenericName[lv]=Zinātnisks Kalkulators
+GenericName[mk]=Научен калкулатор
+GenericName[mt]=Kalkulatriċi xjentifika
+GenericName[nb]=Vitenskaplig kalkulator
+GenericName[nds]=Wetenschaplich Taschenreekner
+GenericName[ne]=वैज्ञानिक गणकयन्त्र
+GenericName[nl]=Wetenschappelijke rekenmachine
+GenericName[nn]=Vitskapleg kalkulator
+GenericName[pa]=ਵਿਗਿਆਨਿਕ ਹਿਸਾਬੀ
+GenericName[pl]=Kalkulator naukowy
+GenericName[pt]=Calculadora Cientifica
+GenericName[pt_BR]=Calculadora CientĂ­fica
+GenericName[ro]=Calculator ştiinţific
+GenericName[ru]=Калькулятор
+GenericName[sk]=Vedecká kalkulačka
+GenericName[sl]=Znanstveni kalkulator
+GenericName[sr]=Научни калкулатор
+GenericName[sr@Latn]=Naučni kalkulator
+GenericName[sv]=Vetenskaplig miniräknare
+GenericName[ta]= அறிவியல் சார்ந்த கணிப்பான்
+GenericName[tg]=Мошинаи ҳисобкунаки Илмӣ
+GenericName[th]=เครื่องคิดเลขแบบวิทยาศาสตร์
+GenericName[tr]=Bilimsel Hesap Makinesi
+GenericName[uk]=Калькулятор для науковців
+GenericName[uz]=Ilmiy kalkulyator
+GenericName[uz@cyrillic]=Илмий калкулятор
+GenericName[ven]=Khalikhuleitha ya tshisaintsi
+GenericName[vi]=Máy tính khoa học
+GenericName[wa]=Carculete syintifike
+GenericName[xh]=Umatshini Wokubala Ezenzululwazi
+GenericName[zh_CN]=科学计算器
+GenericName[zh_TW]=科學計算機
+GenericName[zu]=Umshini wokubala ezenzululwazi
+Terminal=false
+Type=Application
+X-KDE-StartupNotify=true
+Categories=Qt;KDE;Utility;X-KDE-Utilities-Desktop;
diff --git a/kcalc/kcalc.h b/kcalc/kcalc.h
new file mode 100644
index 0000000..0ede211
--- /dev/null
+++ b/kcalc/kcalc.h
@@ -0,0 +1,239 @@
+/*
+ KCalc, a scientific calculator for the X window system using the
+ Qt widget libraries, available at no cost at http://www.troll.no
+
+ Copyright (C) 1996 Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KCALC_H
+#define KCALC_H
+
+class QPushButton;
+class QRadioButton;
+class QButtonGroup;
+class QHButtonGroup;
+class QWidget;
+class DispLogic;
+class Constants;
+#include <kmainwindow.h>
+
+/*
+ Kcalc basically consist of a class for the GUI (here), a class for
+ the display (dlabel.h), and one for the mathematics core
+ (kcalc_core.h).
+
+ When for example '+' is pressed, one sends the contents of the
+ Display and the '+' to the core via "core.Plus(DISPLAY_AMOUNT)".
+ This only updates the core. To bring the changes to the display,
+ use afterwards "UpdateDisplay(true)".
+
+ "UpdateDisplay(true)" means that the amount to be displayed should
+ be taken from the core (get the result of some operation that was
+ performed), "UpdateDisplay(false)" has already the information, what
+ to be display (e.g. user is typing in a number). Note that in the
+ last case the core does not know the number typed in until some
+ operation button is pressed, e.g. "core.Plus(display_number)".
+ */
+
+#include "config.h"
+
+// IMPORTANT this has to come after ../config.h
+#include "kcalc_core.h"
+#include "kcalc_button.h"
+#include "kcalc_const_button.h"
+
+class KCalculator : public KMainWindow
+{
+ Q_OBJECT
+
+public:
+ KCalculator(QWidget *parent = 0, const char *name = 0);
+ ~KCalculator();
+
+signals:
+ void switchInverse(bool);
+ void switchMode(ButtonModeFlags,bool);
+ void switchShowAccels(bool);
+
+private:
+ virtual bool eventFilter( QObject *o, QEvent *e );
+ void updateGeometry();
+ void setupMainActions(void);
+ void setupStatusbar(void);
+ QWidget *setupNumericKeys(QWidget *parent);
+ void setupLogicKeys(QWidget *parent);
+ void setupScientificKeys(QWidget *parent);
+ void setupStatisticKeys(QWidget *parent);
+ void setupConstantsKeys(QWidget *parent);
+ void keyPressEvent(QKeyEvent *e);
+ void keyReleaseEvent(QKeyEvent *e);
+ void set_precision();
+ void set_style();
+ void resetBase(void) { (BaseChooseGroup->find(1))->animateClick();};
+
+ void UpdateDisplay(bool get_amount_from_core = false,
+ bool store_result_in_history = false);
+
+protected slots:
+ void changeButtonNames();
+ void updateSettings();
+ void set_colors();
+ void EnterEqual();
+ void showSettings();
+ void slotStatshow(bool toggled);
+ void slotScientificshow(bool toggled);
+ void slotLogicshow(bool toggled);
+ void slotConstantsShow(bool toggled);
+ void slotShowAll(void);
+ void slotHideAll(void);
+ void slotAngleSelected(int number);
+ void slotBaseSelected(int number);
+ void slotNumberclicked(int number_clicked);
+ void slotEEclicked(void);
+ void slotInvtoggled(bool myboolean);
+ void slotMemRecallclicked(void);
+ void slotMemStoreclicked(void);
+ void slotSinclicked(void);
+ void slotPlusMinusclicked(void);
+ void slotMemPlusMinusclicked(void);
+ void slotCosclicked(void);
+ void slotReciclicked(void);
+ void slotTanclicked(void);
+ void slotFactorialclicked(void);
+ void slotLogclicked(void);
+ void slotSquareclicked(void);
+ void slotLnclicked(void);
+ void slotPowerclicked(void);
+ void slotMCclicked(void);
+ void slotClearclicked(void);
+ void slotACclicked(void);
+ void slotParenOpenclicked(void);
+ void slotParenCloseclicked(void);
+ void slotANDclicked(void);
+ void slotXclicked(void);
+ void slotDivisionclicked(void);
+ void slotORclicked(void);
+ void slotXORclicked(void);
+ void slotPlusclicked(void);
+ void slotMinusclicked(void);
+ void slotLeftShiftclicked(void);
+ void slotRightShiftclicked(void);
+ void slotPeriodclicked(void);
+ void slotEqualclicked(void);
+ void slotPercentclicked(void);
+ void slotRootclicked(void);
+ void slotNegateclicked(void);
+ void slotModclicked(void);
+ void slotStatNumclicked(void);
+ void slotStatMeanclicked(void);
+ void slotStatStdDevclicked(void);
+ void slotStatMedianclicked(void);
+ void slotStatDataInputclicked(void);
+ void slotStatClearDataclicked(void);
+ void slotHyptoggled(bool flag);
+ void slotConstclicked(int);
+
+ void slotConstantToDisplay(int constant);
+ void slotChooseScientificConst0(int option);
+ void slotChooseScientificConst1(int option);
+ void slotChooseScientificConst2(int option);
+ void slotChooseScientificConst3(int option);
+ void slotChooseScientificConst4(int option);
+ void slotChooseScientificConst5(int option);
+
+private:
+ bool inverse;
+ bool hyp_mode;
+ KNumber memory_num;
+ KNumber setvalue;
+
+ // angle modes for trigonometric values
+ enum {
+ DegMode,
+ RadMode,
+ GradMode
+ } _angle_mode;
+
+
+private:
+ QWidget *mSmallPage;
+ QWidget *mLargePage;
+ QWidget *mNumericPage;
+
+ DispLogic* calc_display; // for historic reasons in "dlabel.h"
+ QRadioButton* pbBaseChoose[4];
+ QPushButton* pbAngleChoose;
+ QDict<KCalcButton> pbStat;
+ QDict<KCalcButton> pbScientific;
+ QDict<KCalcButton> pbLogic;
+ KCalcConstButton* pbConstant[10];
+ KCalcButton* pbAC;
+ KCalcButton* pbAND;
+ KCalcButton* pbClear;
+ KCalcButton* pbDivision;
+ KCalcButton* pbEE;
+ KCalcButton* pbEqual;
+ KCalcButton* pbFactorial;
+ KCalcButton* pbInv;
+ KCalcButton* pbMC;
+ KCalcButton* pbMinus;
+ KCalcButton* pbMod;
+ KCalcButton* pbMemPlusMinus;
+ KCalcButton* pbMemRecall;
+ KCalcButton* pbMemStore;
+ KCalcButton* pbOR;
+ KCalcButton* pbParenClose;
+ KCalcButton* pbParenOpen;
+ KCalcButton* pbPercent;
+ KCalcButton* pbPeriod;
+ KCalcButton* pbPlus;
+ KCalcButton* pbPlusMinus;
+ KCalcButton* pbPower;
+ KCalcButton* pbReci;
+ KSquareButton* pbRoot;
+ KCalcButton* pbSquare;
+ KCalcButton* pbX;
+ KCalcButton* pbXOR;
+
+ Constants * tmp_const; // this is the dialog for configuring const
+ // buttons would like to remove this, but
+ // don't know how
+
+ QHButtonGroup* BaseChooseGroup;
+ // NumButtonGroup: 0-9 = digits, 0xA-0xF = hex-keys
+ QButtonGroup* NumButtonGroup;
+ // ConstButtonGroup C1-C6
+ QButtonGroup* ConstButtonGroup;
+
+ KToggleAction *actionStatshow;
+ KToggleAction *actionScientificshow;
+ KToggleAction *actionLogicshow;
+ KToggleAction *actionConstantsShow;
+
+ QPtrList<KCalcButton> mFunctionButtonList;
+ QPtrList<KCalcButton> mStatButtonList;
+ QPtrList<KCalcButton> mMemButtonList;
+ QPtrList<KCalcButton> mOperationButtonList;
+
+ int mInternalSpacing;
+
+ CalcEngine core;
+};
+
+#endif // KCALC_H
diff --git a/kcalc/kcalc.kcfg b/kcalc/kcalc.kcfg
new file mode 100644
index 0000000..e4275b7
--- /dev/null
+++ b/kcalc/kcalc.kcfg
@@ -0,0 +1,127 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <include>kapplication.h</include>
+ <include>kglobalsettings.h</include>
+ <include>config.h</include>
+ <kcfgfile name="kcalcrc"/>
+ <group name="Colors">
+ <entry name="ForeColor" type="Color">
+ <label>The foreground color of the display.</label>
+ <default>#000000</default>
+ </entry>
+ <entry name="BackColor" type="Color">
+ <label>The background color of the display.</label>
+ <default>#BDFFB4</default>
+ </entry>
+ <entry name="NumberButtonsColor" type="Color">
+ <label>The color of number buttons.</label>
+ <code>QColor defaultButtonColor = kapp->palette().active().background();</code>
+ <default code="true">defaultButtonColor</default>
+ </entry>
+ <entry name="FunctionButtonsColor" type="Color">
+ <label>The color of function buttons.</label>
+ <default code="true">defaultButtonColor</default>
+ </entry>
+ <entry name="StatButtonsColor" type="Color">
+ <label>The color of statistical buttons.</label>
+ <default code="true">defaultButtonColor</default>
+ </entry>
+ <entry name="HexButtonsColor" type="Color">
+ <label>The color of hex buttons.</label>
+ <default code="true">defaultButtonColor</default>
+ </entry>
+ <entry name="MemoryButtonsColor" type="Color">
+ <label>The color of memory buttons.</label>
+ <default code="true">defaultButtonColor</default>
+ </entry>
+ <entry name="OperationButtonsColor" type="Color">
+ <label>The color of operation buttons.</label>
+ <default code="true">defaultButtonColor</default>
+ </entry>
+ </group>
+ <group name="Font">
+ <entry name="Font" type="Font">
+ <label>The font to use in the display.</label>
+ <default code="true">QFont(KGlobalSettings::generalFont().family(), 14, QFont::Bold)</default>
+ </entry>
+ </group>
+ <group name="Precision">
+ <entry name="Precision" type="UInt" key="precision">
+ <label>Maximum number of digits displayed.</label>
+ <whatsthis>
+ KCalc can compute with many more digits than the number that
+ fits on the display. This setting gives the maximum number of
+ digits displayed, before KCalc starts using scientific notation,
+ i.e. notation of the type 2.34e12.
+ </whatsthis>
+ <default>12</default>
+ <min>8</min>
+ <max>200</max>
+ </entry>
+ <entry name="FixedPrecision" type="UInt" key="fixedprecision">
+ <label>Number of fixed decimal digits.</label>
+ <default>2</default>
+ </entry>
+ <entry name="Fixed" type="Bool" key="fixed">
+ <label>Whether to use fixed decimal places.</label>
+ <default>false</default>
+ </entry>
+ </group>
+ <group name="General">
+ <entry name="Beep" type="Bool" key="beep">
+ <label>Whether to beep on error.</label>
+ <default>true</default>
+ </entry>
+ <entry name="CaptionResult" type="Bool" key="captionresult">
+ <label>Whether to show the result in the window title.</label>
+ <default>false</default>
+ </entry>
+ <entry name="GroupDigits" type="Bool" key="groupdigits">
+ <label>Whether to group digits.</label>
+ <default>true</default>
+ </entry>
+ <entry name="ShowStat" type="Bool">
+ <label>Whether to show statistical buttons.</label>
+ <default>false</default>
+ </entry>
+ <entry name="ShowScientific" type="Bool">
+ <label>Whether to show buttons with functions used in science/engineering,
+ like exp, log, sin etc.</label>
+ <default>false</default>
+ </entry>
+ <entry name="ShowLogic" type="Bool">
+ <label>Whether to show logic buttons.</label>
+ <default>false</default>
+ </entry>
+ <entry name="ShowConstants" type="Bool">
+ <label>Whether to show constant buttons.</label>
+ <default>false</default>
+ </entry>
+ </group>
+ <group name="UserConstants">
+ <entry name="nameConstant$(ConstIndex)" type="String" key="nameConstant$(ConstIndex)">
+ <label>Name of the user programmable constants.</label>
+ <parameter name="ConstIndex" type="Int" max="5"/>
+ <default param="0">C1</default>
+ <default param="1">C2</default>
+ <default param="2">C3</default>
+ <default param="3">C4</default>
+ <default param="4">C5</default>
+ <default param="5">C6</default>
+ </entry>
+
+ <entry name="valueConstant$(ConstIndex)" type="String" key="valueConstant$(ConstIndex)">
+ <label>List of user programmable constants</label>
+ <parameter name="ConstIndex" type="Int" max="5"/>
+ <default param="0">0</default>
+ <default param="1">0</default>
+ <default param="2">0</default>
+ <default param="3">0</default>
+ <default param="4">0</default>
+ <default param="5">0</default>
+ </entry>
+ </group>
+</kcfg>
diff --git a/kcalc/kcalc_button.cpp b/kcalc/kcalc_button.cpp
new file mode 100644
index 0000000..7021a1a
--- /dev/null
+++ b/kcalc/kcalc_button.cpp
@@ -0,0 +1,168 @@
+/*
+ kCalculator, a simple scientific calculator for KDE
+
+ Copyright (C) 1996-2000 Bernd Johannes Wuebben
+ wuebben@kde.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <qsimplerichtext.h>
+#include <qtooltip.h>
+#include <qpainter.h>
+
+
+#include "qdom.h"
+
+#include "kcalc_button.h"
+
+
+KCalcButton::KCalcButton(QWidget * parent, const char * name)
+ : KPushButton(parent, name), _show_accel_mode(false),
+ _mode_flags(ModeNormal)
+{
+ setAutoDefault(false);
+}
+
+KCalcButton::KCalcButton(const QString &label, QWidget * parent,
+ const char * name, const QString &tooltip)
+ : KPushButton(label, parent, name), _show_accel_mode(false), _mode_flags(ModeNormal)
+{
+ setAutoDefault(false);
+ addMode(ModeNormal, label, tooltip);
+}
+
+void KCalcButton::addMode(ButtonModeFlags mode, QString label, QString tooltip, bool is_label_richtext)
+{
+ if (_mode.contains(mode)) _mode.remove(mode);
+
+ _mode[mode] = ButtonMode(label, tooltip, is_label_richtext);
+
+ // Need to put each button into default mode first
+ if(mode == ModeNormal) slotSetMode(ModeNormal, true);
+}
+
+void KCalcButton::slotSetMode(ButtonModeFlags mode, bool flag)
+{
+ ButtonModeFlags new_mode;
+
+ if (flag) { // if the specified mode is to be set (i.e. flag = true)
+ new_mode = ButtonModeFlags(_mode_flags | mode);
+ } else if (_mode_flags && mode) { // if the specified mode is to be cleared (i.e. flag = false)
+ new_mode = ButtonModeFlags(_mode_flags - mode);
+ } else {
+ return; // nothing to do
+ }
+
+ if (_mode.contains(new_mode)) {
+ // save accel, because setting label erases accel
+ QKeySequence _accel = accel();
+
+ if(_mode[new_mode].is_label_richtext)
+ _label = _mode[new_mode].label;
+ else
+ setText(_mode[new_mode].label);
+ QToolTip::remove(this);
+ QToolTip::add(this, _mode[new_mode].tooltip);
+ _mode_flags = new_mode;
+
+ // restore accel
+ setAccel(_accel);
+ }
+
+ // this is necessary for people pressing CTRL and changing mode at
+ // the same time...
+ if (_show_accel_mode) slotSetAccelDisplayMode(true);
+
+ update();
+}
+
+static QString escape(QString str)
+{
+ str.replace('&', "&&");
+ return str;
+}
+
+
+void KCalcButton::slotSetAccelDisplayMode(bool flag)
+{
+ _show_accel_mode = flag;
+
+ // save accel, because setting label erases accel
+ QKeySequence _accel = accel();
+
+ if (flag == true) {
+ setText(escape(QString(accel())));
+ } else {
+ setText(_mode[_mode_flags].label);
+ }
+
+ // restore accel
+ setAccel(_accel);
+}
+
+void KCalcButton::paintLabel(QPainter *paint)
+{
+ if (_mode[_mode_flags].is_label_richtext) {
+ QSimpleRichText _text(_label, font());
+ _text.draw(paint, width()/2-_text.width()/2, 0, childrenRegion(), colorGroup());
+ } else {
+ KPushButton::drawButtonLabel(paint);
+ }
+}
+
+void KCalcButton::drawButtonLabel(QPainter *paint)
+{
+ if (_show_accel_mode) {
+ KPushButton::drawButtonLabel(paint);
+ } else if (_mode.contains(_mode_flags)) {
+ paintLabel(paint);
+ }
+}
+
+
+void KSquareButton::paintLabel(QPainter *paint)
+{
+ int w = width();
+ int w2 = w/2 - 13;
+ int h = height();
+ int h2 = h/2 - 7;
+ // in some KDE-styles (.NET, Phase,...) we have to set the painter back to the right color
+ paint->setPen(foregroundColor());
+ // these statements are for the improved
+ // representation of the sqrt function
+ paint->drawLine(w2, 11 + h2, w2 + 2, 7 + h2);
+ paint->drawLine(w2 + 2, 7 + h2, w2 + 4, 14 + h2);
+ paint->drawLine(w2 + 4, 14 + h2, w2 + 6, 1 + h2);
+ paint->drawLine(w2 + 6, 1 + h2, w2 + 27, 1 + h2);
+ paint->drawLine(w2 + 27, 1 + h2, w2 + 27, 4 + h2);
+ // add a three for the cube root
+ if (_mode_flags & ModeInverse) {
+ paint->drawText(w2-2, 9 + h2, "ł");
+ }
+}
+
+void KSquareButton::drawButtonLabel(QPainter *paint)
+{
+ if (_show_accel_mode) {
+ KPushButton::drawButtonLabel(paint);
+ } else if (_mode.contains(_mode_flags)) {
+ paintLabel(paint);
+ }
+}
+
+#include "kcalc_button.moc"
+
diff --git a/kcalc/kcalc_button.h b/kcalc/kcalc_button.h
new file mode 100644
index 0000000..0998b5f
--- /dev/null
+++ b/kcalc/kcalc_button.h
@@ -0,0 +1,105 @@
+/*
+ KCalc, a scientific calculator for the X window system using the
+ Qt widget libraries, available at no cost at http://www.troll.no
+
+ Copyright (C) 1996 Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _KCALC_BUTTON_H
+#define _KCALC_BUTTON_H
+
+#include <kpushbutton.h>
+
+// The class KCalcButton is an overriden KPushButton. It offers extra
+// functionality e.g. labels can be richtext or the accels can be
+// shown in the label, but the most important thing is that the button
+// may have several modes with corresponding labels. When one switches
+// modes, the corresponding label is displayed.
+
+
+enum ButtonModeFlags {ModeNormal = 0, ModeInverse = 1, ModeHyperbolic = 2};
+
+class QDomNode;
+
+// Each kcalc button can be in one of several modes.
+// The following class describes label, tooltip etc. for each mode...
+class ButtonMode
+{
+public:
+ ButtonMode(void) {};
+ ButtonMode(QString &label, QString &tooltip, bool is_label_richtext)
+ : is_label_richtext(is_label_richtext), tooltip(tooltip)
+ {
+ if (is_label_richtext)
+ this->label = "<qt type=\"page\"><center>" + label + "</center></qt>";
+ else
+ this->label = label;
+ };
+
+ QString label;
+ bool is_label_richtext;
+ QString tooltip;
+};
+
+
+class KCalcButton : public KPushButton
+{
+Q_OBJECT
+
+public:
+ KCalcButton(QWidget *parent, const char * name = 0);
+ KCalcButton(const QString &label, QWidget *parent, const char * name = 0,
+ const QString &tooltip = QString());
+
+ void addMode(ButtonModeFlags mode, QString label, QString tooltip, bool is_label_richtext = false);
+
+public slots:
+ void slotSetMode(ButtonModeFlags mode, bool flag);
+ void slotSetAccelDisplayMode(bool flag);
+
+protected:
+ virtual void drawButtonLabel(QPainter *paint);
+ void paintLabel(QPainter *paint);
+
+protected:
+ bool _show_accel_mode;
+ QString _label;
+
+ ButtonModeFlags _mode_flags;
+
+ QMap<ButtonModeFlags, ButtonMode> _mode;
+};
+
+class KSquareButton : public KCalcButton
+{
+Q_OBJECT
+
+public:
+ KSquareButton(QWidget *parent, const char * name = 0)
+ : KCalcButton(parent, name) { };
+ KSquareButton(const QString &label, QWidget *parent, const char * name = 0,
+ const QString &tooltip = QString())
+ : KCalcButton(label, parent, name, tooltip) { };
+
+protected:
+ virtual void drawButtonLabel(QPainter *paint);
+ void paintLabel(QPainter *paint);
+};
+
+#endif // _KCALC_BUTTON_H
diff --git a/kcalc/kcalc_const_button.cpp b/kcalc/kcalc_const_button.cpp
new file mode 100644
index 0000000..e9c4216
--- /dev/null
+++ b/kcalc/kcalc_const_button.cpp
@@ -0,0 +1,109 @@
+/*
+ kCalculator, a simple scientific calculator for KDE
+
+ Copyright (C) 2003 Klaus Niederkrueger <kniederk@math.uni-koeln.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <qstring.h>
+
+
+#include <kcmenumngr.h>
+#include <kinputdialog.h>
+#include <kpopupmenu.h>
+
+#include "kcalc_const_button.h"
+#include "kcalc_const_menu.h"
+#include "kcalc_settings.h"
+
+
+KCalcConstButton::KCalcConstButton(QWidget *parent, int but_num, const char * name)
+ : KCalcButton(parent, name), _button_num(but_num)
+{
+ addMode(ModeInverse, "Store", i18n("Write display data into memory"));
+
+ initPopupMenu();
+}
+
+
+KCalcConstButton::KCalcConstButton(const QString &label, QWidget *parent, int but_num,
+ const char * name, const QString &tooltip)
+ : KCalcButton(label, parent, name, tooltip), _button_num(but_num)
+{
+ addMode(ModeInverse, "Store", i18n("Write display data into memory"));
+
+ initPopupMenu();
+}
+
+QString KCalcConstButton::constant(void) const
+{
+ return KCalcSettings::valueConstant(_button_num);
+}
+
+void KCalcConstButton::setLabelAndTooltip(void)
+{
+ QString new_label = QString("C") + QString().setNum(_button_num + 1);
+ QString new_tooltip;
+
+ new_label = (KCalcSettings::nameConstant(_button_num).isNull() ? new_label : KCalcSettings::nameConstant(_button_num));
+
+ new_tooltip = new_label + "=" + KCalcSettings::valueConstant(_button_num);
+
+ addMode(ModeNormal, new_label, new_tooltip);
+}
+
+void KCalcConstButton::initPopupMenu(void)
+{
+ KCalcConstMenu *tmp_menu = new KCalcConstMenu(this);
+
+ _popup = new KPopupMenu(this, "set const-cutton");
+ _popup->insertItem(i18n("Set Name"), 0);
+ _popup->insertItem(i18n("Choose From List"), tmp_menu, 1);
+
+ connect(_popup, SIGNAL(activated(int)), SLOT(slotConfigureButton(int)));
+ connect(tmp_menu, SIGNAL(activated(int)), SLOT(slotChooseScientificConst(int)));
+
+ KContextMenuManager::insert(this, _popup);
+}
+
+void KCalcConstButton::slotConfigureButton(int option)
+{
+ if (option == 0)
+ {
+ bool yes_no;
+ QString input = KInputDialog::text(i18n("New Name for Constant"), i18n("New name:"),
+ text(), &yes_no, this, "nameUserConstants-Dialog");
+ if(yes_no) {
+ KCalcSettings::setNameConstant(_button_num, input);
+ setLabelAndTooltip();
+ }
+ }
+}
+
+void KCalcConstButton::slotChooseScientificConst(int option)
+{
+ KCalcSettings::setValueConstant(_button_num,
+ KCalcConstMenu::Constants[option].value);
+
+ KCalcSettings::setNameConstant(_button_num,
+ KCalcConstMenu::Constants[option].label);
+
+ setLabelAndTooltip();
+}
+
+#include "kcalc_const_button.moc"
+
diff --git a/kcalc/kcalc_const_button.h b/kcalc/kcalc_const_button.h
new file mode 100644
index 0000000..18ebf3e
--- /dev/null
+++ b/kcalc/kcalc_const_button.h
@@ -0,0 +1,58 @@
+/*
+ KCalc, a scientific calculator for the X window system using the
+ Qt widget libraries, available at no cost at http://www.troll.no
+
+ Copyright (C) 1996 Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _KCALC_CONST_BUTTON_H
+#define _KCALC_CONST_BUTTON_H
+
+#include <klocale.h>
+#include "kcalc_button.h"
+
+
+class KCalcConstButton : public KCalcButton
+{
+Q_OBJECT
+
+ public:
+
+ KCalcConstButton(QWidget *parent, int but_num, const char * name = 0);
+
+ KCalcConstButton(const QString &label, QWidget *parent, int but_num, const char * name = 0,
+ const QString &tooltip = QString());
+
+ QString constant(void) const;
+
+ void setLabelAndTooltip(void);
+
+ private slots:
+ void slotConfigureButton(int option);
+ void slotChooseScientificConst(int option);
+
+ private:
+ void initPopupMenu(void);
+
+ KPopupMenu* _popup;
+ int _button_num;
+};
+
+
+#endif // _KCALC_CONST_BUTTON_H
diff --git a/kcalc/kcalc_const_menu.cpp b/kcalc/kcalc_const_menu.cpp
new file mode 100644
index 0000000..77bb02e
--- /dev/null
+++ b/kcalc/kcalc_const_menu.cpp
@@ -0,0 +1,89 @@
+/*
+ kCalculator, a simple scientific calculator for KDE
+
+ Copyright (C) 2003 Klaus Niederkrueger <kniederk@math.uni-koeln.de>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <klocale.h>
+
+#include "kcalc_const_menu.h"
+
+#define NUM_CONST 17
+
+const struct science_constant KCalcConstMenu::Constants[] = {
+ {QString::fromUtf8("π"), I18N_NOOP("Pi"), "",
+ "3.1415926535897932384626433832795028841971693993751"
+ "05820974944592307816406286208998628034825342117068", Mathematics},
+ {"e", I18N_NOOP("Euler Number"), "",
+ "2.7182818284590452353602874713526624977572470936999"
+ "59574966967627724076630353547594571382178525166427", Mathematics},
+ {QString::fromUtf8("φ"), I18N_NOOP("Golden Ratio"), "", "1.61803398874989484820458683436563811", Mathematics},
+ {"c", I18N_NOOP("Light Speed"), "", "2.99792458e8", Electromagnetic},
+ {"h", I18N_NOOP("Planck's Constant"), "", "6.6260693e-34", Nuclear},
+ {"G", I18N_NOOP("Constant of Gravitation"), "", "6.6742e-11", Gravitation},
+ {"g", I18N_NOOP("Earth Acceleration"), "", "9.80665", Gravitation},
+ {"e", I18N_NOOP("Elementary Charge"), "", "1.60217653e-19", ConstantCategory(Electromagnetic|Nuclear)},
+ {"Z_0", I18N_NOOP("Impedance of Vacuum"), "", "376.730313461", Electromagnetic},
+ {QString::fromUtf8("Îą"), I18N_NOOP("Fine-Structure Constant"), "", "7.297352568e-3", Nuclear},
+ {QString::fromUtf8("Îź")+"_0", I18N_NOOP("Permeability of Vacuum"), "", "1.2566370614e-6", Electromagnetic},
+ {QString::fromUtf8("Îľ")+"_0", I18N_NOOP("Permittivity of vacuum"), "", "8.854187817e-12", Electromagnetic},
+ {"k", I18N_NOOP("Boltzmann Constant"), "", "1.3806505e-23", Thermodynamics},
+ {"1u", I18N_NOOP("Atomic Mass Unit"), "", "1.66053886e-27", Thermodynamics},
+ {"R", I18N_NOOP("Molar Gas Constant"), "", "8.314472", Thermodynamics},
+ {QString::fromUtf8("σ"), I18N_NOOP("Stefan-Boltzmann Constant"), "", "5.670400e-8", Thermodynamics},
+ {"N_A", I18N_NOOP("Avogadro's Number"), "", "6.0221415e23", Thermodynamics}
+};
+
+KCalcConstMenu::KCalcConstMenu(QWidget * parent, const char * name)
+ : QPopupMenu(parent, name)
+{
+ QPopupMenu *math_menu = new QPopupMenu(this, "mathematical constants");
+ QPopupMenu *em_menu = new QPopupMenu(this, "electromagnetic constants");
+ QPopupMenu *nuclear_menu = new QPopupMenu(this, "nuclear constants");
+ QPopupMenu *thermo_menu = new QPopupMenu(this, "thermodynamics constants");
+ QPopupMenu *gravitation_menu = new QPopupMenu(this, "gravitation constants");
+
+ insertItem(i18n("Mathematics"), math_menu);
+ insertItem(i18n("Electromagnetism"), em_menu);
+ insertItem(i18n("Atomic && Nuclear"), nuclear_menu);
+ insertItem(i18n("Thermodynamics"), thermo_menu);
+ insertItem(i18n("Gravitation"), gravitation_menu);
+
+ connect(math_menu, SIGNAL(activated(int)), this, SLOT(slotPassActivate(int)));
+ connect(em_menu, SIGNAL(activated(int)), this, SLOT(slotPassActivate(int)));
+ connect(nuclear_menu, SIGNAL(activated(int)), this, SLOT(slotPassActivate(int)));
+ connect(thermo_menu, SIGNAL(activated(int)), this, SLOT(slotPassActivate(int)));
+ connect(gravitation_menu, SIGNAL(activated(int)), this, SLOT(slotPassActivate(int)));
+
+
+ for (int i = 0; i<NUM_CONST; i++) {
+ if(Constants[i].category & Mathematics)
+ math_menu->insertItem(i18n(Constants[i].name), i);
+ if(Constants[i].category & Electromagnetic)
+ em_menu->insertItem(i18n(Constants[i].name), i);
+ if(Constants[i].category & Nuclear)
+ nuclear_menu->insertItem(i18n(Constants[i].name), i);
+ if(Constants[i].category & Thermodynamics)
+ thermo_menu->insertItem(i18n(Constants[i].name), i);
+ if(Constants[i].category & Gravitation)
+ gravitation_menu->insertItem(i18n(Constants[i].name), i);
+ }
+}
+
+
+#include "kcalc_const_menu.moc"
diff --git a/kcalc/kcalc_const_menu.h b/kcalc/kcalc_const_menu.h
new file mode 100644
index 0000000..4ae8da3
--- /dev/null
+++ b/kcalc/kcalc_const_menu.h
@@ -0,0 +1,55 @@
+/*
+ KCalc, a scientific calculator for the X window system using the
+ Qt widget libraries, available at no cost at http://www.troll.no
+
+ Copyright (C) 2004 Klaus Niederkruger
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _KCALC_CONST_MENU_H
+#define _KCALC_CONST_MENU_H
+
+#include <qpopupmenu.h>
+#include <qstring.h>
+
+enum ConstantCategory {Mathematics = 1, Electromagnetic = 2, Nuclear = 4, Thermodynamics = 8, Gravitation = 16};
+
+struct science_constant{
+ QString label;
+ const char * name;
+ QString whatsthis;
+ QString value;
+ ConstantCategory category;
+};
+
+class KCalcConstMenu : public QPopupMenu
+{
+Q_OBJECT
+
+ public:
+ KCalcConstMenu(QWidget * parent = 0, const char * name = 0);
+
+ static const struct science_constant Constants[];
+
+public slots:
+ void slotPassActivate(int item)
+ {
+ emit activated(item);
+ };
+};
+
+#endif // _KCALC_CONST_MENU_H
diff --git a/kcalc/kcalc_core.cpp b/kcalc/kcalc_core.cpp
new file mode 100644
index 0000000..4270895
--- /dev/null
+++ b/kcalc/kcalc_core.cpp
@@ -0,0 +1,1004 @@
+/*
+ kCalculator, a scientific calculator for the X window system using the
+ Qt widget libraries, available at no cost at http://www.troll.no
+
+ The stack engine contained in this file was take from
+ Martin Bartlett's xfrmcalc
+
+ portions: Copyright (C) 2003-2006 Klaus Niederkrueger
+
+ portions: Copyright (C) 1996 Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+
+ portions: Copyright (C) 1995 Martin Bartlett
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+
+#if defined(_ISOC99_SOURCE)
+ #include <cassert>
+ #include <cstdio>
+ #include <climits>
+ #include <csignal>
+ #include <cerrno>
+ #include <cstring>
+ using namespace std;
+#else
+ #include <limits.h>
+ #include <stdio.h>
+ #include <assert.h>
+ #include <signal.h>
+ #include <errno.h>
+ #include <string.h>
+#endif
+
+#include <config.h>
+#include "kcalc_core.h"
+#include <stdlib.h>
+#include <klocale.h>
+#include <kmessagebox.h>
+#include "kcalctype.h"
+
+#ifndef HAVE_FUNC_ISINF
+ #ifdef HAVE_IEEEFP_H
+ #include <ieeefp.h>
+ #else
+ #include <math.h>
+ #endif
+
+#undef isinf
+int isinf(double x)
+{
+#ifdef _HPUX_SOURCE
+return !isfinite(x) && x == x;
+#else
+return !finite(x) && x==x;
+#endif
+}
+
+#endif
+
+
+static void fpe_handler(int fpe_parm)
+{
+ UNUSED(fpe_parm);
+ // display_error = true;
+ //tmp_number = 0L;
+}
+
+
+static bool _error;
+
+static KNumber ExecOr(const KNumber & left_op, const KNumber & right_op)
+{
+ return (left_op | right_op);
+}
+
+static KNumber ExecXor(const KNumber & left_op, const KNumber & right_op)
+{
+ return (left_op | right_op) - (left_op & right_op);
+}
+
+static KNumber ExecAnd(const KNumber & left_op, const KNumber & right_op)
+{
+ return (left_op & right_op);
+}
+
+static KNumber ExecLsh(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op << right_op;
+}
+
+static KNumber ExecRsh(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op >> right_op;
+}
+
+static KNumber ExecAdd(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op + right_op;
+}
+
+static KNumber ExecSubtract(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op - right_op;
+}
+
+static KNumber ExecMultiply(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op * right_op;
+}
+
+static KNumber ExecDivide(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op / right_op;
+}
+
+static KNumber ExecMod(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op % right_op;
+}
+
+static KNumber ExecIntDiv(const KNumber & left_op, const KNumber & right_op)
+{
+ return (left_op / right_op).integerPart();
+}
+
+bool isoddint(const KNumber & input)
+{
+ if (input.type() != KNumber::IntegerType) return false;
+ // Routine to check if KNumber is an Odd integer
+ return ( (input / KNumber(2)).type() == KNumber::IntegerType);
+}
+
+static KNumber ExecPower(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op.power(right_op);
+}
+
+static KNumber ExecPwrRoot(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op.power(KNumber::One / right_op);
+}
+
+static KNumber ExecAddP(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op * (KNumber::One + right_op/KNumber(100));
+}
+
+static KNumber ExecSubP(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op * (KNumber::One - right_op/KNumber(100));
+}
+
+static KNumber ExecMultiplyP(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op * right_op / KNumber(100);
+}
+
+static KNumber ExecDivideP(const KNumber & left_op, const KNumber & right_op)
+{
+ return left_op * KNumber(100) / right_op;
+}
+
+
+// build precedence list
+const struct operator_data CalcEngine::Operator[] = {
+ { 0, NULL, NULL}, // FUNC_EQUAL
+ { 0, NULL, NULL}, // FUNC_PERCENT
+ { 0, NULL, NULL}, // FUNC_BRACKET
+ { 1, ExecOr, NULL}, // FUNC_OR
+ { 2, ExecXor, NULL}, // FUNC_XOR
+ { 3, ExecAnd, NULL}, // FUNC_AND
+ { 4, ExecLsh, NULL}, // FUNC_LSH
+ { 4, ExecRsh, NULL}, // FUNC_RSH
+ { 5, ExecAdd, ExecAddP}, // FUNC_ADD
+ { 5, ExecSubtract, ExecSubP}, // FUNC_SUBTRACT
+ { 6, ExecMultiply, ExecMultiplyP}, // FUNC_MULTIPLY
+ { 6, ExecDivide, ExecDivideP}, // FUNC_DIVIDE
+ { 6, ExecMod, NULL}, // FUNC_MOD
+ { 6, ExecIntDiv, NULL}, // FUNC_INTDIV
+ { 7, ExecPower, NULL}, // FUNC_POWER
+ { 7, ExecPwrRoot, NULL} // FUNC_PWR_ROOT
+};
+
+
+CalcEngine::CalcEngine()
+ : _percent_mode(false)
+{
+ //
+ // Basic initialization involves initializing the calcultion
+ // stack, and setting up the floating point excetion signal
+ // handler to trap the errors that the code can/has not been
+ // written to trap.
+ //
+
+ struct sigaction fpe_trap;
+
+ sigemptyset(&fpe_trap.sa_mask);
+ fpe_trap.sa_handler = &fpe_handler;
+#ifdef SA_RESTART
+ fpe_trap.sa_flags = SA_RESTART;
+#endif
+ sigaction(SIGFPE, &fpe_trap, NULL);
+
+ _last_number = KNumber::Zero;
+ _error = false;
+}
+
+KNumber CalcEngine::lastOutput(bool &error) const
+{
+ error = _error;
+ return _last_number;
+}
+
+void CalcEngine::ArcCosDeg(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType ||
+ input < -KNumber::One || input > KNumber::One) {
+ _last_number = KNumber("nan");
+ return;
+ }
+
+ if (input.type() == KNumber::IntegerType) {
+ if (input == KNumber::One) {
+ _last_number = KNumber::Zero;
+ return;
+ }
+ if (input == - KNumber::One) {
+ _last_number = KNumber(180);
+ return;
+ }
+ if (input == KNumber::Zero) {
+ _last_number = KNumber(90);
+ return;
+ }
+ }
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = Rad2Deg(KNumber(double(ACOS(tmp_num))));
+}
+
+void CalcEngine::ArcCosRad(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType ||
+ input < -KNumber::One || input > KNumber::One) {
+ _last_number = KNumber("nan");
+ return;
+ }
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(ACOS(tmp_num)));
+}
+
+void CalcEngine::ArcCosGrad(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType ||
+ input < -KNumber::One || input > KNumber::One) {
+ _last_number = KNumber("nan");
+ return;
+ }
+ if (input.type() == KNumber::IntegerType) {
+ if (input == KNumber::One) {
+ _last_number = KNumber::Zero;
+ return;
+ }
+ if (input == - KNumber::One) {
+ _last_number = KNumber(200);
+ return;
+ }
+ if (input == KNumber::Zero) {
+ _last_number = KNumber(100);
+ return;
+ }
+ }
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = Rad2Gra(KNumber(double(ACOS(tmp_num))));
+}
+
+void CalcEngine::ArcSinDeg(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType ||
+ input < -KNumber::One || input > KNumber::One) {
+ _last_number = KNumber("nan");
+ return;
+ }
+ if (input.type() == KNumber::IntegerType) {
+ if (input == KNumber::One) {
+ _last_number = KNumber(90);
+ return;
+ }
+ if (input == - KNumber::One) {
+ _last_number = KNumber(-90);
+ return;
+ }
+ if (input == KNumber::Zero) {
+ _last_number = KNumber(0);
+ return;
+ }
+ }
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = Rad2Deg(KNumber(double(ASIN(tmp_num))));
+}
+
+void CalcEngine::ArcSinRad(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType ||
+ input < -KNumber::One || input > KNumber::One) {
+ _last_number = KNumber("nan");
+ return;
+ }
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(ASIN(tmp_num)));
+}
+
+void CalcEngine::ArcSinGrad(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType ||
+ input < -KNumber::One || input > KNumber::One) {
+ _last_number = KNumber("nan");
+ return;
+ }
+ if (input.type() == KNumber::IntegerType) {
+ if (input == KNumber::One) {
+ _last_number = KNumber(100);
+ return;
+ }
+ if (input == - KNumber::One) {
+ _last_number = KNumber(-100);
+ return;
+ }
+ if (input == KNumber::Zero) {
+ _last_number = KNumber(0);
+ return;
+ }
+ }
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = Rad2Gra(KNumber(double(ASIN(tmp_num))));
+}
+
+void CalcEngine::ArcTangensDeg(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ if (input == KNumber("nan")) _last_number = KNumber("nan");
+ if (input == KNumber("inf")) _last_number = KNumber(90);
+ if (input == KNumber("-inf")) _last_number = KNumber(-90);
+ return;
+ }
+
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = Rad2Deg(KNumber(double(ATAN(tmp_num))));
+}
+
+void CalcEngine::ArcTangensRad(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ if (input == KNumber("nan")) _last_number = KNumber("nan");
+ if (input == KNumber("inf"))
+ _last_number = KNumber::Pi/KNumber(2);
+ if (input == KNumber("-inf"))
+ _last_number = -KNumber::Pi/KNumber(2);
+ return;
+ }
+
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(ATAN(tmp_num)));
+}
+
+void CalcEngine::ArcTangensGrad(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ if (input == KNumber("nan")) _last_number = KNumber("nan");
+ if (input == KNumber("inf")) _last_number = KNumber(100);
+ if (input == KNumber("-inf")) _last_number = KNumber(-100);
+ return;
+ }
+
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = Rad2Gra(KNumber(double(ATAN(tmp_num))));
+}
+
+void CalcEngine::AreaCosHyp(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ if (input == KNumber("nan")) _last_number = KNumber("nan");
+ if (input == KNumber("inf")) _last_number = KNumber("inf");
+ if (input == KNumber("-inf")) _last_number = KNumber("nan");
+ return;
+ }
+
+ if (input < KNumber::One) {
+ _last_number = KNumber("nan");
+ return;
+ }
+ if (input == KNumber::One) {
+ _last_number = KNumber::Zero;
+ return;
+ }
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(ACOSH(tmp_num)));
+}
+
+void CalcEngine::AreaSinHyp(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ if (input == KNumber("nan")) _last_number = KNumber("nan");
+ if (input == KNumber("inf")) _last_number = KNumber("inf");
+ if (input == KNumber("-inf")) _last_number = KNumber("-inf");
+ return;
+ }
+
+ if (input == KNumber::Zero) {
+ _last_number = KNumber::Zero;
+ return;
+ }
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(ASINH(tmp_num)));
+}
+
+void CalcEngine::AreaTangensHyp(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ _last_number = KNumber("nan");
+ return;
+ }
+
+ if (input < -KNumber::One || input > KNumber::One) {
+ _last_number = KNumber("nan");
+ return;
+ }
+ if (input == KNumber::One) {
+ _last_number = KNumber("inf");
+ return;
+ }
+ if (input == - KNumber::One) {
+ _last_number = KNumber("-inf");
+ return;
+ }
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(ATANH(tmp_num)));
+}
+
+void CalcEngine::Complement(KNumber input)
+{
+ if (input.type() != KNumber::IntegerType)
+ {
+ _last_number = KNumber("nan");
+ return;
+ }
+ _last_number = - input - KNumber::One;
+}
+
+
+
+// move a number into the interval [0,360) by adding multiples of 360
+static KNumber const moveIntoDegInterval(KNumber const &num)
+{
+ KNumber tmp_num = num - (num/KNumber(360)).integerPart() * KNumber(360);
+ if(tmp_num < KNumber::Zero)
+ return tmp_num + KNumber(360);
+ return tmp_num;
+}
+
+// move a number into the interval [0,400) by adding multiples of 400
+static KNumber const moveIntoGradInterval(KNumber const &num)
+{
+ KNumber tmp_num = num - (num/KNumber(400)).integerPart() * KNumber(400);
+ if(tmp_num < KNumber::Zero)
+ return tmp_num + KNumber(400);
+ return tmp_num;
+}
+
+
+void CalcEngine::CosDeg(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ _last_number = KNumber("nan");
+ return;
+ }
+ KNumber trunc_input = moveIntoDegInterval(input);
+ if (trunc_input.type() == KNumber::IntegerType) {
+ KNumber mult = trunc_input/KNumber(90);
+ if (mult.type() == KNumber::IntegerType) {
+ if (mult == KNumber::Zero)
+ _last_number = 1;
+ else if (mult == KNumber(1))
+ _last_number = 0;
+ else if (mult == KNumber(2))
+ _last_number = -1;
+ else if (mult == KNumber(3))
+ _last_number = 0;
+ else qDebug("Something wrong in CalcEngine::CosDeg\n");
+ return;
+ }
+ }
+ trunc_input = Deg2Rad(trunc_input);
+
+ CALCAMNT tmp_num = static_cast<double>(trunc_input);
+ _last_number = KNumber(double(COS(tmp_num)));
+}
+
+void CalcEngine::CosRad(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ _last_number = KNumber("nan");
+ return;
+ }
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(COS(tmp_num)));
+}
+
+void CalcEngine::CosGrad(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ _last_number = KNumber("nan");
+ return;
+ }
+ KNumber trunc_input = moveIntoGradInterval(input);
+ if (trunc_input.type() == KNumber::IntegerType) {
+ KNumber mult = trunc_input/KNumber(100);
+ if (mult.type() == KNumber::IntegerType) {
+ if (mult == KNumber::Zero)
+ _last_number = 1;
+ else if (mult == KNumber(1))
+ _last_number = 0;
+ else if (mult == KNumber(2))
+ _last_number = -1;
+ else if (mult == KNumber(3))
+ _last_number = 0;
+ else qDebug("Something wrong in CalcEngine::CosGrad\n");
+ return;
+ }
+ }
+ trunc_input = Gra2Rad(trunc_input);
+
+ CALCAMNT tmp_num = static_cast<double>(trunc_input);
+ _last_number = KNumber(double(COS(tmp_num)));
+}
+
+void CalcEngine::CosHyp(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ if (input == KNumber("nan")) _last_number = KNumber("nan");
+ if (input == KNumber("inf")) _last_number = KNumber("inf");
+ if (input == KNumber("-inf")) _last_number = KNumber("inf");
+ return;
+ }
+
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(COSH(tmp_num)));
+}
+
+void CalcEngine::Cube(KNumber input)
+{
+ _last_number = input*input*input;
+}
+
+void CalcEngine::CubeRoot(KNumber input)
+{
+ _last_number = input.cbrt();
+}
+
+void CalcEngine::Exp(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ if (input == KNumber("nan")) _last_number = KNumber("nan");
+ if (input == KNumber("inf")) _last_number = KNumber("inf");
+ if (input == KNumber("-inf")) _last_number = KNumber::Zero;
+ return;
+ }
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(EXP(tmp_num)));
+}
+
+void CalcEngine::Exp10(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ if (input == KNumber("nan")) _last_number = KNumber("nan");
+ if (input == KNumber("inf")) _last_number = KNumber("inf");
+ if (input == KNumber("-inf")) _last_number = KNumber::Zero;
+ return;
+ }
+ _last_number = KNumber(10).power(input);
+}
+
+
+static KNumber _factorial(KNumber input)
+{
+ KNumber tmp_amount = input;
+
+ // don't do recursive factorial,
+ // because large numbers lead to
+ // stack overflows
+ while (tmp_amount > KNumber::One)
+ {
+ tmp_amount -= KNumber::One;
+
+ input = tmp_amount * input;
+
+ }
+
+ if (tmp_amount < KNumber::One)
+ return KNumber::One;
+ return input;
+}
+
+
+void CalcEngine::Factorial(KNumber input)
+{
+ if (input == KNumber("inf")) return;
+ if (input < KNumber::Zero || input.type() == KNumber::SpecialType)
+ {
+ _error = true;
+ _last_number = KNumber("nan");
+ return;
+ }
+ KNumber tmp_amount = input.integerPart();
+
+ _last_number = _factorial(tmp_amount);
+}
+
+void CalcEngine::InvertSign(KNumber input)
+{
+ _last_number = -input;
+}
+
+void CalcEngine::Ln(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ if (input == KNumber("nan")) _last_number = KNumber("nan");
+ if (input == KNumber("inf")) _last_number = KNumber("inf");
+ if (input == KNumber("-inf")) _last_number = KNumber("nan");
+ return;
+ }
+ if (input < KNumber::Zero)
+ _last_number = KNumber("nan");
+ else if (input == KNumber::Zero)
+ _last_number = KNumber("-inf");
+ else if (input == KNumber::One)
+ _last_number = 0;
+ else {
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(LN(tmp_num)));
+ }
+}
+
+void CalcEngine::Log10(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ if (input == KNumber("nan")) _last_number = KNumber("nan");
+ if (input == KNumber("inf")) _last_number = KNumber("inf");
+ if (input == KNumber("-inf")) _last_number = KNumber("nan");
+ return;
+ }
+ if (input < KNumber::Zero)
+ _last_number = KNumber("nan");
+ else if (input == KNumber::Zero)
+ _last_number = KNumber("-inf");
+ else if (input == KNumber::One)
+ _last_number = 0;
+ else {
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(LOG_TEN(tmp_num)));
+ }
+}
+
+void CalcEngine::ParenClose(KNumber input)
+{
+ // evaluate stack until corresponding opening bracket
+ while (!_stack.isEmpty())
+ {
+ _node tmp_node = _stack.pop();
+ if (tmp_node.operation == FUNC_BRACKET)
+ break;
+ input = evalOperation(tmp_node.number, tmp_node.operation,
+ input);
+ }
+ _last_number = input;
+ return;
+}
+
+void CalcEngine::ParenOpen(KNumber input)
+{
+ enterOperation(input, FUNC_BRACKET);
+}
+
+void CalcEngine::Reciprocal(KNumber input)
+{
+ _last_number = KNumber::One/input;
+}
+
+
+void CalcEngine::SinDeg(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ _last_number = KNumber("nan");
+ return;
+ }
+
+ KNumber trunc_input = moveIntoDegInterval(input);
+ if (trunc_input.type() == KNumber::IntegerType) {
+ KNumber mult = trunc_input/KNumber(90);
+ if (mult.type() == KNumber::IntegerType) {
+ if (mult == KNumber::Zero)
+ _last_number = 0;
+ else if (mult == KNumber(1))
+ _last_number = 1;
+ else if (mult == KNumber(2))
+ _last_number = 0;
+ else if (mult == KNumber(3))
+ _last_number = -1;
+ else qDebug("Something wrong in CalcEngine::SinDeg\n");
+ return;
+ }
+ }
+ trunc_input = Deg2Rad(trunc_input);
+
+ CALCAMNT tmp_num = static_cast<double>(trunc_input);
+ _last_number = KNumber(double(SIN(tmp_num)));
+}
+
+void CalcEngine::SinRad(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ _last_number = KNumber("nan");
+ return;
+ }
+
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(SIN(tmp_num)));
+}
+
+void CalcEngine::SinGrad(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ _last_number = KNumber("nan");
+ return;
+ }
+
+ KNumber trunc_input = moveIntoGradInterval(input);
+ if (trunc_input.type() == KNumber::IntegerType) {
+ KNumber mult = trunc_input/KNumber(100);
+ if (mult.type() == KNumber::IntegerType) {
+ if (mult == KNumber::Zero)
+ _last_number = 0;
+ else if (mult == KNumber(1))
+ _last_number = 1;
+ else if (mult == KNumber(2))
+ _last_number = 0;
+ else if (mult == KNumber(3))
+ _last_number = -1;
+ else qDebug("Something wrong in CalcEngine::SinGrad\n");
+ return;
+ }
+ }
+
+ trunc_input = Gra2Rad(trunc_input);
+
+ CALCAMNT tmp_num = static_cast<double>(trunc_input);
+ _last_number = KNumber(double(SIN(tmp_num)));
+}
+
+void CalcEngine::SinHyp(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ if (input == KNumber("nan")) _last_number = KNumber("nan");
+ if (input == KNumber("inf")) _last_number = KNumber("inf");
+ if (input == KNumber("-inf")) _last_number = KNumber("-inf");
+ return;
+ }
+
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(SINH(tmp_num)));
+}
+
+void CalcEngine::Square(KNumber input)
+{
+ _last_number = input*input;
+}
+
+void CalcEngine::SquareRoot(KNumber input)
+{
+ _last_number = input.sqrt();
+}
+
+void CalcEngine::StatClearAll(KNumber input)
+{
+ UNUSED(input);
+ stats.clearAll();
+}
+
+void CalcEngine::StatCount(KNumber input)
+{
+ UNUSED(input);
+ _last_number = KNumber(stats.count());
+}
+
+void CalcEngine::StatDataNew(KNumber input)
+{
+ stats.enterData(input);
+ _last_number = KNumber(stats.count());
+}
+
+void CalcEngine::StatDataDel(KNumber input)
+{
+ UNUSED(input);
+ stats.clearLast();
+ _last_number = KNumber::Zero;
+}
+
+void CalcEngine::StatMean(KNumber input)
+{
+ UNUSED(input);
+ _last_number = stats.mean();
+
+ _error = stats.error();
+}
+
+void CalcEngine::StatMedian(KNumber input)
+{
+ UNUSED(input);
+ _last_number = stats.median();
+
+ _error = stats.error();
+}
+
+void CalcEngine::StatStdDeviation(KNumber input)
+{
+ UNUSED(input);
+ _last_number = stats.std();
+
+ _error = stats.error();
+}
+
+void CalcEngine::StatStdSample(KNumber input)
+{
+ UNUSED(input);
+ _last_number = stats.sample_std();
+
+ _error = stats.error();
+}
+
+void CalcEngine::StatSum(KNumber input)
+{
+ UNUSED(input);
+ _last_number = stats.sum();
+}
+
+void CalcEngine::StatSumSquares(KNumber input)
+{
+ UNUSED(input);
+ _last_number = stats.sum_of_squares();
+
+ _error = stats.error();
+}
+
+void CalcEngine::TangensDeg(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ _last_number = KNumber("nan");
+ return;
+ }
+
+ SinDeg(input);
+ KNumber arg1 = _last_number;
+ CosDeg(input);
+ KNumber arg2 = _last_number;
+ _last_number = arg1 / arg2;
+}
+
+void CalcEngine::TangensRad(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ _last_number = KNumber("nan");
+ return;
+ }
+
+ SinRad(input);
+ KNumber arg1 = _last_number;
+ CosRad(input);
+ KNumber arg2 = _last_number;
+ _last_number = arg1 / arg2;
+}
+
+void CalcEngine::TangensGrad(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ _last_number = KNumber("nan");
+ return;
+ }
+
+ SinGrad(input);
+ KNumber arg1 = _last_number;
+ CosGrad(input);
+ KNumber arg2 = _last_number;
+ _last_number = arg1 / arg2;
+}
+
+void CalcEngine::TangensHyp(KNumber input)
+{
+ if (input.type() == KNumber::SpecialType) {
+ if (input == KNumber("nan")) _last_number = KNumber("nan");
+ if (input == KNumber("inf")) _last_number = KNumber::One;
+ if (input == KNumber("-inf")) _last_number = KNumber::MinusOne;
+ return;
+ }
+
+ CALCAMNT tmp_num = static_cast<double>(input);
+ _last_number = KNumber(double(TANH(tmp_num)));
+}
+
+KNumber CalcEngine::evalOperation(KNumber arg1, Operation operation,
+ KNumber arg2)
+{
+ if (!_percent_mode || Operator[operation].prcnt_ptr == NULL)
+ {
+ return (Operator[operation].arith_ptr)(arg1, arg2);
+ } else {
+ _percent_mode = false;
+ return (Operator[operation].prcnt_ptr)(arg1, arg2);
+ }
+}
+
+void CalcEngine::enterOperation(KNumber number, Operation func)
+{
+ _node tmp_node;
+
+ if (func == FUNC_BRACKET)
+ {
+ tmp_node.number = 0;
+ tmp_node.operation = FUNC_BRACKET;
+
+ _stack.push(tmp_node);
+
+ return;
+ }
+
+ if (func == FUNC_PERCENT)
+ {
+ _percent_mode = true;
+ }
+
+ tmp_node.number = number;
+ tmp_node.operation = func;
+
+ _stack.push(tmp_node);
+
+ evalStack();
+}
+
+bool CalcEngine::evalStack(void)
+{
+ // this should never happen
+ if (_stack.isEmpty()) KMessageBox::error(0L, i18n("Stack processing error - empty stack"));
+
+ _node tmp_node = _stack.pop();
+
+ while (! _stack.isEmpty())
+ {
+ _node tmp_node2 = _stack.pop();
+ if (Operator[tmp_node.operation].precedence <=
+ Operator[tmp_node2.operation].precedence)
+ {
+ if (tmp_node2.operation == FUNC_BRACKET) continue;
+ KNumber tmp_result =
+ evalOperation(tmp_node2.number, tmp_node2.operation,
+ tmp_node.number);
+ tmp_node.number = tmp_result;
+ }
+ else
+ {
+ _stack.push(tmp_node2);
+ break;
+ }
+
+ }
+
+ if(tmp_node.operation != FUNC_EQUAL && tmp_node.operation != FUNC_PERCENT)
+ _stack.push(tmp_node);
+
+ _last_number = tmp_node.number;
+ return true;
+}
+
+void CalcEngine::Reset()
+{
+ _error = false;
+ _last_number = KNumber::Zero;
+
+ _stack.clear();
+}
+
+
diff --git a/kcalc/kcalc_core.h b/kcalc/kcalc_core.h
new file mode 100644
index 0000000..edd33f3
--- /dev/null
+++ b/kcalc/kcalc_core.h
@@ -0,0 +1,181 @@
+/*
+
+ KCalc, a scientific calculator for the X window system using the
+ Qt widget libraries, available at no cost at http://www.troll.no
+
+ Copyright (C) 1996 Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef _KCALC_CORE_H
+#define _KCALC_CORE_H
+
+#include "stats.h"
+#include <qvaluestack.h>
+#include "knumber.h"
+
+#define POS_ZERO 1e-19L /* What we consider zero is */
+#define NEG_ZERO -1e-19L /* anything between these two */
+
+
+typedef KNumber (*Arith)(const KNumber &, const KNumber &);
+typedef KNumber (*Prcnt)(const KNumber &, const KNumber &);
+
+#define UNUSED(x) ((void)(x))
+
+
+
+struct operator_data {
+ int precedence; // priority of operators in " enum Operation"
+ Arith arith_ptr;
+ Prcnt prcnt_ptr;
+};
+
+class CalcEngine
+{
+ public:
+ // operations that can be stored in calculation stack
+ enum Operation {
+ FUNC_EQUAL,
+ FUNC_PERCENT,
+ FUNC_BRACKET,
+ FUNC_OR,
+ FUNC_XOR,
+ FUNC_AND,
+ FUNC_LSH,
+ FUNC_RSH,
+ FUNC_ADD,
+ FUNC_SUBTRACT,
+ FUNC_MULTIPLY,
+ FUNC_DIVIDE,
+ FUNC_MOD,
+ FUNC_INTDIV,
+ FUNC_POWER,
+ FUNC_PWR_ROOT
+ };
+
+ CalcEngine();
+
+ KNumber lastOutput(bool &error) const;
+
+ void enterOperation(KNumber num, Operation func);
+
+
+ void ArcCosDeg(KNumber input);
+ void ArcCosRad(KNumber input);
+ void ArcCosGrad(KNumber input);
+ void ArcSinDeg(KNumber input);
+ void ArcSinRad(KNumber input);
+ void ArcSinGrad(KNumber input);
+ void ArcTangensDeg(KNumber input);
+ void ArcTangensRad(KNumber input);
+ void ArcTangensGrad(KNumber input);
+ void AreaCosHyp(KNumber input);
+ void AreaSinHyp(KNumber input);
+ void AreaTangensHyp(KNumber input);
+ void Complement(KNumber input);
+ void CosDeg(KNumber input);
+ void CosRad(KNumber input);
+ void CosGrad(KNumber input);
+ void CosHyp(KNumber input);
+ void Cube(KNumber input);
+ void CubeRoot(KNumber input);
+ void Exp(KNumber input);
+ void Exp10(KNumber input);
+ void Factorial(KNumber input);
+ void InvertSign(KNumber input);
+ void Ln(KNumber input);
+ void Log10(KNumber input);
+ void ParenClose(KNumber input);
+ void ParenOpen(KNumber input);
+ void Reciprocal(KNumber input);
+ void SinDeg(KNumber input);
+ void SinGrad(KNumber input);
+ void SinRad(KNumber input);
+ void SinHyp(KNumber input);
+ void Square(KNumber input);
+ void SquareRoot(KNumber input);
+ void StatClearAll(KNumber input);
+ void StatCount(KNumber input);
+ void StatDataNew(KNumber input);
+ void StatDataDel(KNumber input);
+ void StatMean(KNumber input);
+ void StatMedian(KNumber input);
+ void StatStdDeviation(KNumber input);
+ void StatStdSample(KNumber input);
+ void StatSum(KNumber input);
+ void StatSumSquares(KNumber input);
+ void TangensDeg(KNumber input);
+ void TangensRad(KNumber input);
+ void TangensGrad(KNumber input);
+ void TangensHyp(KNumber input);
+
+ void Reset();
+ private:
+ KStats stats;
+
+ typedef struct {
+ KNumber number;
+ Operation operation;
+ } _node;
+
+ // Stack holds all operations and numbers that have not yet been
+ // processed, e.g. user types "2+3*", the calculation can not be
+ // executed, because "*" has a higher precedence than "+", so we
+ // need to wait for the next number.
+ //
+ // In the stack this would be stored as ((2,+),(3,*),...)
+ //
+ // "enterOperation": If the introduced Operation has lower priority
+ // than the preceding operations in the stack, then we can start to
+ // evaluate the stack (with "evalStack"). Otherwise we append the new
+ // Operation and number to the stack.
+ //
+ // E.g. "2*3+" evaluates to "6+", but "2+3*" can not be evaluated
+ // yet.
+ //
+ // We also take care of brackets, by writing a marker "FUNC_BRACKET"
+ // into the stack, each time the user opens one. When a bracket is
+ // closed, everything in the stack is evaluated until the first
+ // marker "FUNC_BRACKET" found.
+ QValueStack<_node> _stack;
+
+ KNumber _last_number;
+
+ bool _percent_mode;
+
+
+ static const struct operator_data Operator[];
+
+ bool evalStack(void);
+
+ KNumber evalOperation(KNumber arg1, Operation operation, KNumber arg2);
+
+ const KNumber Deg2Rad(const KNumber &x) const
+ { return KNumber(2) * KNumber::Pi / KNumber(360) * x; }
+ const KNumber Gra2Rad(const KNumber &x) const
+ { return KNumber(2)*KNumber::Pi / KNumber(400) * x; }
+ const KNumber Rad2Deg(const KNumber &x) const
+ { return KNumber(360) / (KNumber(2) * KNumber::Pi) * x; }
+ const KNumber Rad2Gra(const KNumber &x) const
+ { return KNumber(400) / (KNumber(2)*KNumber::Pi) * x; }
+
+};
+
+
+#endif //_KCALC_CORE_H
diff --git a/kcalc/kcalc_settings.kcfgc b/kcalc/kcalc_settings.kcfgc
new file mode 100644
index 0000000..ac8bd41
--- /dev/null
+++ b/kcalc/kcalc_settings.kcfgc
@@ -0,0 +1,8 @@
+# Code generation options for kconfig_compiler
+File=kcalc.kcfg
+ClassName=KCalcSettings
+Singleton=true
+Mutators=ShowStat,ShowScientific,ShowLogic,ShowConstants,nameConstant,valueConstant
+# Inherits=KConfigSkeleton
+# IncludeFiles=libkdepim/kpimprefs.h
+# MemberVariables=public
diff --git a/kcalc/kcalcdisplay.cpp b/kcalc/kcalcdisplay.cpp
new file mode 100644
index 0000000..672c363
--- /dev/null
+++ b/kcalc/kcalcdisplay.cpp
@@ -0,0 +1,608 @@
+/*
+ $Id$
+
+ KCalc, a scientific calculator for the X window system using the
+ Qt widget libraries, available at no cost at http://www.troll.no
+
+ Copyright (C) 1996 Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#include <errno.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#include <qclipboard.h>
+#include <qpainter.h>
+#include <qregexp.h>
+
+#include <kglobal.h>
+#include <klocale.h>
+#include <knotifyclient.h>
+#include "kcalc_settings.h"
+#include "kcalcdisplay.h"
+#include "kcalcdisplay.moc"
+
+
+KCalcDisplay::KCalcDisplay(QWidget *parent, const char *name)
+ :QLabel(parent,name), _beep(false), _groupdigits(false), _button(0), _lit(false),
+ _num_base(NB_DECIMAL), _precision(9),
+ _fixed_precision(-1), _display_amount(0),
+ selection_timer(new QTimer)
+{
+ setFrameStyle(QFrame::WinPanel | QFrame::Sunken);
+ setAlignment(AlignRight | AlignVCenter);
+ setFocus();
+ setFocusPolicy(QWidget::StrongFocus);
+ setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed, false);
+
+ connect(this, SIGNAL(clicked()), this, SLOT(slotDisplaySelected()));
+
+ connect(selection_timer, SIGNAL(timeout()),
+ this, SLOT(slotSelectionTimedOut()));
+
+ sendEvent(EventReset);
+}
+
+KCalcDisplay::~KCalcDisplay()
+{
+ delete selection_timer;
+}
+
+bool KCalcDisplay::sendEvent(Event const event)
+{
+ switch(event)
+ {
+ case EventReset:
+ _display_amount = 0;
+ _str_int = "0";
+ _str_int_exp = QString::null;
+
+ _eestate = false;
+ _period = false;
+ _neg_sign = false;
+
+ updateDisplay();
+
+ return true;
+ case EventClear:
+ return sendEvent(EventReset);
+ case EventChangeSign:
+ return changeSign();
+ case EventError:
+ updateDisplay();
+
+ return true;
+ default:
+ return false;
+ }
+}
+
+
+void KCalcDisplay::slotCut(void)
+{
+ slotCopy();
+ sendEvent(EventReset);
+}
+
+void KCalcDisplay::slotCopy(void)
+{
+ QString txt = QLabel::text();
+ if (_num_base == NB_HEX)
+ txt.prepend( "0x" );
+ (QApplication::clipboard())->setText(txt, QClipboard::Clipboard);
+ (QApplication::clipboard())->setText(txt, QClipboard::Selection);
+}
+
+void KCalcDisplay::slotPaste(bool bClipboard)
+{
+ QString tmp_str = (QApplication::clipboard())->text(bClipboard ? QClipboard::Clipboard : QClipboard::Selection);
+
+ if (tmp_str.isNull())
+ {
+ if (_beep) KNotifyClient::beep();
+ return;
+ }
+
+ NumBase tmp_num_base = _num_base;
+
+ tmp_str = tmp_str.stripWhiteSpace();
+
+ if (tmp_str.startsWith("0x", false))
+ tmp_num_base = NB_HEX;
+
+ if (tmp_num_base != NB_DECIMAL)
+ {
+ bool was_ok;
+ unsigned long long int tmp_result = tmp_str.toULongLong(& was_ok, tmp_num_base);
+
+ if (!was_ok)
+ {
+ setAmount(KNumber::NotDefined);
+ if(_beep) KNotifyClient::beep();
+ return ;
+ }
+
+ setAmount(KNumber(tmp_result));
+ }
+ else // _num_base == NB_DECIMAL && ! tmp_str.startsWith("0x", false)
+ {
+ setAmount(KNumber(tmp_str));
+ if (_beep && _display_amount == KNumber::NotDefined)
+ KNotifyClient::beep();
+ }
+}
+
+void KCalcDisplay::slotDisplaySelected(void)
+{
+ if(_button == LeftButton) {
+ if(_lit) {
+ slotCopy();
+ selection_timer->start(100);
+ } else {
+ selection_timer->stop();
+ }
+
+ invertColors();
+ } else {
+ slotPaste(false); // Selection
+ }
+}
+
+void KCalcDisplay::slotSelectionTimedOut(void)
+{
+ _lit = false;
+ invertColors();
+ selection_timer->stop();
+}
+
+void KCalcDisplay::invertColors()
+{
+ QColor tmp_col(paletteBackgroundColor());
+ setPaletteBackgroundColor(paletteForegroundColor());
+ setPaletteForegroundColor(tmp_col);
+}
+
+
+
+void KCalcDisplay::mousePressEvent(QMouseEvent *e)
+{
+ if(e->button() == LeftButton) {
+ _lit = !_lit;
+ _button = LeftButton;
+ } else {
+ _button = MidButton;
+ }
+
+ emit clicked();
+}
+
+void KCalcDisplay::setPrecision(int precision)
+{
+ _precision = precision;
+}
+
+void KCalcDisplay::setFixedPrecision(int precision)
+{
+ if (_fixed_precision > _precision)
+ _fixed_precision = -1;
+ else
+ _fixed_precision = precision;
+}
+
+void KCalcDisplay::setBeep(bool flag)
+{
+ _beep = flag;
+}
+
+void KCalcDisplay::setGroupDigits(bool flag)
+{
+ _groupdigits = flag;
+}
+
+KNumber const & KCalcDisplay::getAmount(void) const
+{
+ return _display_amount;
+}
+
+
+bool KCalcDisplay::setAmount(KNumber const & new_amount)
+{
+ QString display_str;
+
+ _str_int = "0";
+ _str_int_exp = QString::null;
+ _period = false;
+ _neg_sign = false;
+ _eestate = false;
+
+ if (_num_base != NB_DECIMAL && new_amount.type() != KNumber::SpecialType)
+ {
+ _display_amount = new_amount.integerPart();
+ unsigned long long int tmp_workaround = static_cast<unsigned long long int>(_display_amount);
+
+ display_str = QString::number(tmp_workaround, _num_base).upper();
+ }
+ else // _num_base == NB_DECIMAL || new_amount.type() ==
+ // KNumber::SpecialType
+ {
+ _display_amount = new_amount;
+
+ display_str = _display_amount.toQString(KCalcSettings::precision(), _fixed_precision);
+#if 0
+ else if (_display_amount > 1.0e+16)
+ display_str = QCString().sprintf(PRINT_LONG_BIG, _precision + 1, _display_amount);
+ else
+ display_str = QCString().sprintf(PRINT_LONG_BIG, _precision, _display_amount);
+#endif
+ }
+
+ setText(display_str);
+ return true;
+
+}
+
+void KCalcDisplay::setText(QString const &string)
+{
+ QString localizedString = string;
+
+ // If we aren't in decimal mode, we don't need to modify the string
+ if (_num_base == NB_DECIMAL && _groupdigits)
+ // when input ends with "." (because uncomplete), the
+ // formatNumber-method does not work; fix by hand by
+ // truncating, formatting and appending again
+ if (string.endsWith(".")) {
+ localizedString.truncate(localizedString.length() - 1);
+ localizedString = KGlobal::locale()->formatNumber(localizedString, false, 0); // Note: rounding happened already above!
+ localizedString.append(KGlobal::locale()->decimalSymbol());
+ } else
+ localizedString = KGlobal::locale()->formatNumber(string, false, 0); // Note: rounding happened already above!
+
+ QLabel::setText(localizedString);
+ emit changedText(localizedString);
+}
+
+QString KCalcDisplay::text() const
+{
+ if (_num_base != NB_DECIMAL)
+ return QLabel::text();
+ QString display_str = _display_amount.toQString(KCalcSettings::precision());
+
+ return display_str;
+ // return QCString().sprintf(PRINT_LONG_BIG, 40, _display_amount);
+}
+
+/* change representation of display to new base (i.e. binary, decimal,
+ octal, hexadecimal). The amount being displayed is changed to this
+ base, but for now this amount can not be modified anymore (like
+ being set with "setAmount"). Return value is the new base. */
+int KCalcDisplay::setBase(NumBase new_base)
+{
+ CALCAMNT tmp_val = static_cast<unsigned long long int>(getAmount());
+
+ switch(new_base)
+ {
+ case NB_HEX:
+ _num_base = NB_HEX;
+ _period = false;
+ break;
+ case NB_DECIMAL:
+ _num_base = NB_DECIMAL;
+ break;
+ case NB_OCTAL:
+ _num_base = NB_OCTAL;
+ _period = false;
+ break;
+ case NB_BINARY:
+ _num_base = NB_BINARY;
+ _period = false;
+ break;
+ default: // we shouldn't ever end up here
+ _num_base = NB_DECIMAL;
+ }
+
+ setAmount(static_cast<unsigned long long int>(tmp_val));
+
+ return _num_base;
+}
+
+void KCalcDisplay::setStatusText(uint i, const QString& text)
+{
+ if (i < NUM_STATUS_TEXT)
+ _str_status[i] = text;
+ update();
+}
+
+bool KCalcDisplay::updateDisplay(void)
+{
+ // Put sign in front.
+ QString tmp_string;
+ if(_neg_sign == true)
+ tmp_string = "-" + _str_int;
+ else
+ tmp_string = _str_int;
+
+ switch(_num_base)
+ {
+ case NB_BINARY:
+ Q_ASSERT(_period == false && _eestate == false);
+ setText(tmp_string);
+ _display_amount = static_cast<unsigned long long int>(STRTOUL(_str_int.latin1(), 0, 2));
+ if (_neg_sign)
+ _display_amount = -_display_amount;
+ //str_size = cvb(_str_int, boh_work, DSP_SIZE);
+ break;
+
+ case NB_OCTAL:
+ Q_ASSERT(_period == false && _eestate == false);
+ setText(tmp_string);
+ _display_amount = static_cast<unsigned long long int>(STRTOUL(_str_int.latin1(), 0, 8));
+ if (_neg_sign)
+ _display_amount = -_display_amount;
+ break;
+
+ case NB_HEX:
+ Q_ASSERT(_period == false && _eestate == false);
+ setText(tmp_string);
+ _display_amount = static_cast<unsigned long long int>(STRTOUL(_str_int.latin1(), 0, 16));
+ if (_neg_sign)
+ _display_amount = -_display_amount;
+ break;
+
+ case NB_DECIMAL:
+ if(_eestate == false)
+ {
+ setText(tmp_string);
+ _display_amount = tmp_string;
+ }
+ else
+ {
+ if(_str_int_exp.isNull())
+ {
+ // add 'e0' to display but not to conversion
+ _display_amount = tmp_string;
+ setText(tmp_string + "e0");
+ }
+ else
+ {
+ tmp_string += 'e' + _str_int_exp;
+ setText(tmp_string);
+ _display_amount = tmp_string;
+ }
+ }
+ break;
+
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+void KCalcDisplay::newCharacter(char const new_char)
+{
+ // test if character is valid
+ switch(new_char)
+ {
+ case 'e':
+ // EE can be set only once and in decimal mode
+ if (_num_base != NB_DECIMAL ||
+ _eestate == true)
+ {
+ if(_beep) KNotifyClient::beep();
+ return;
+ }
+ _eestate = true;
+ break;
+
+ case '.':
+ // Period can be set only once and only in decimal
+ // mode, also not in EE-mode
+ if (_num_base != NB_DECIMAL ||
+ _period == true ||
+ _eestate == true)
+ {
+ if(_beep) KNotifyClient::beep();
+ return;
+ }
+ _period = true;
+ break;
+
+ case 'F':
+ case 'E':
+ case 'D':
+ case 'C':
+ case 'B':
+ case 'A':
+ if (_num_base == NB_DECIMAL)
+ {
+ if(_beep) KNotifyClient::beep();
+ return;
+ }
+ // no break
+ case '9':
+ case '8':
+ if (_num_base == NB_OCTAL)
+ {
+ if(_beep) KNotifyClient::beep();
+ return;
+ }
+ // no break
+ case '7':
+ case '6':
+ case '5':
+ case '4':
+ case '3':
+ case '2':
+ if (_num_base == NB_BINARY)
+ {
+ if(_beep) KNotifyClient::beep();
+ return;
+ }
+ // no break
+ case '1':
+ case '0':
+ break;
+
+ default:
+ if(_beep) KNotifyClient::beep();
+ return;
+ }
+
+ // change exponent or mantissa
+ if (_eestate)
+ {
+ // ignore ',' before 'e'. turn e.g. '123.e' into '123e'
+ if (new_char == 'e' && _str_int.endsWith( "." ))
+ {
+ _str_int.truncate(_str_int.length() - 1);
+ _period = false;
+ }
+
+ // 'e' only starts ee_mode, leaves strings unchanged
+ if (new_char != 'e' &&
+ // do not add '0' if at start of exp
+ !(_str_int_exp.isNull() && new_char == '0'))
+ _str_int_exp.append(new_char);
+ }
+ else
+ {
+ // handle first character
+ if (_str_int == "0")
+ {
+ switch(new_char)
+ {
+ case '.':
+ // display "0." not just "."
+ _str_int.append(new_char);
+ break;
+ case 'e':
+ // display "0e" not just "e"
+ // "0e" does not make sense either, but...
+ _str_int.append(new_char);
+ break;
+ default:
+ // no leading '0's
+ _str_int[0] = new_char;
+ }
+ }
+ else
+ _str_int.append(new_char);
+ }
+
+ updateDisplay();
+}
+
+void KCalcDisplay::deleteLastDigit(void)
+{
+ // Only partially implemented !!
+ if (_eestate)
+ {
+ if(_str_int_exp.isNull())
+ {
+ _eestate = false;
+ }
+ else
+ {
+ int length = _str_int_exp.length();
+ if(length > 1)
+ {
+ _str_int_exp.truncate(length-1);
+ }
+ else
+ {
+ _str_int_exp = (char *)0;
+ }
+ }
+ }
+ else
+ {
+ int length = _str_int.length();
+ if(length > 1)
+ {
+ if (_str_int[length-1] == '.')
+ _period = false;
+ _str_int.truncate(length-1);
+ }
+ else
+ {
+ Q_ASSERT(_period == false);
+ _str_int[0] = '0';
+ }
+ }
+
+ updateDisplay();
+}
+
+// change Sign of display. Problem: Only possible here, when in input
+// mode. Otherwise return 'false' so that the kcalc_core can handle
+// things.
+bool KCalcDisplay::changeSign(void)
+{
+ //stupid way, to see if in input_mode or display_mode
+ if (_str_int == "0") return false;
+
+ if(_eestate)
+ {
+ if(!_str_int_exp.isNull())
+ {
+ if (_str_int_exp[0] != '-')
+ _str_int_exp.prepend('-');
+ else
+ _str_int_exp.remove('-');
+ }
+ }
+ else
+ {
+ _neg_sign = ! _neg_sign;
+ }
+
+ updateDisplay();
+
+ return true;
+}
+
+void KCalcDisplay::drawContents(QPainter *p)
+{
+ QLabel::drawContents(p);
+
+ // draw the status texts using half of the normal
+ // font size but not smaller than 7pt
+ QFont f(font());
+ f.setPointSize(QMAX((f.pointSize() / 2), 7));
+ p->setFont(f);
+ QFontMetrics fm(f);
+ uint w = fm.width("_____");
+ uint h = fm.height();
+
+ for (uint i = 0; i < NUM_STATUS_TEXT; i++)
+ {
+ p->drawText(5 + i * w, h, _str_status[i]);
+ }
+}
+
+// Return the QLabel's normal size hint vertically expanded
+// by half the font height to make room for the status texts
+QSize KCalcDisplay::sizeHint() const
+{
+ QFont f(font());
+ f.setPointSize(QMAX((f.pointSize() / 2), 7));
+ QFontMetrics fm(f);
+ return QLabel::sizeHint() + QSize(0, fm.height());
+}
+
diff --git a/kcalc/kcalcdisplay.h b/kcalc/kcalcdisplay.h
new file mode 100644
index 0000000..4f72fb7
--- /dev/null
+++ b/kcalc/kcalcdisplay.h
@@ -0,0 +1,152 @@
+/*
+
+ KCalc
+
+ Copyright (C) Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+ wuebben@kde.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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+ */
+
+
+#ifndef _D_KCALCDISPLAY_H_
+#define _D_KCALCDISPLAY_H_
+
+#include <stdlib.h>
+#include <qlabel.h>
+#include <qtimer.h>
+#include "knumber.h"
+#include "kcalctype.h"
+
+#if defined HAVE_LONG_DOUBLE && defined HAVE_L_FUNCS
+ #define PRINT_FLOAT "%.*Lf"
+ #define PRINT_LONG_BIG "%.*Lg"
+ #define PRINT_LONG "%Lg"
+#else
+ #define PRINT_FLOAT "%.*f"
+ #define PRINT_LONG_BIG "%.*g"
+ #define PRINT_LONG "%g"
+#endif
+
+#ifdef HAVE_LONG_LONG
+ #define PRINT_OCTAL "%llo"
+ #define PRINT_HEX "%llX"
+#else
+ #define PRINT_OCTAL "%lo"
+ #define PRINT_HEX "%lX"
+#endif
+
+#define NUM_STATUS_TEXT 4
+
+/*
+ This class provides a pocket calculator display. The display has
+ implicitely two major modes: One is for editing and one is purely
+ for displaying.
+
+ When one uses "setAmount", the given amount is displayed, and the
+ amount which was possibly typed in before is lost. At the same time
+ this new value can not be modified.
+
+ On the other hand, "addNewChar" adds a new digit to the amount that
+ is being typed in. If "setAmount" was used before, the display is
+ cleared and a new input starts.
+
+ TODO: Check overflows, number of digits and such...
+*/
+
+enum NumBase {
+ NB_BINARY = 2,
+ NB_OCTAL = 8,
+ NB_DECIMAL = 10,
+ NB_HEX = 16
+};
+
+
+class KCalcDisplay : public QLabel
+{
+Q_OBJECT
+
+public:
+ KCalcDisplay(QWidget *parent=0, const char *name=0);
+ ~KCalcDisplay();
+
+protected:
+ void mousePressEvent ( QMouseEvent *);
+ virtual void drawContents(QPainter *p);
+
+public:
+ enum Event {
+ EventReset, // resets display
+ EventClear, // if no _error reset display
+ EventError,
+ EventChangeSign
+ };
+ bool sendEvent(Event const event);
+ void deleteLastDigit(void);
+ KNumber const & getAmount(void) const;
+ void newCharacter(char const new_char);
+ bool setAmount(KNumber const & new_amount);
+ int setBase(NumBase new_base);
+ void setBeep(bool flag);
+ void setGroupDigits(bool flag);
+ void setFixedPrecision(int precision);
+ void setPrecision(int precision);
+ void setText(QString const &string);
+ QString text() const;
+ bool updateDisplay(void);
+ void setStatusText(uint i, const QString& text);
+ virtual QSize sizeHint() const;
+private:
+ bool _beep;
+ bool _groupdigits;
+ int _button;
+ bool _lit;
+ NumBase _num_base;
+
+ int _precision;
+ int _fixed_precision; // "-1" = no fixed_precision
+
+ KNumber _display_amount;
+private:
+ bool changeSign(void);
+ void invertColors(void);
+
+ // only used for input of new numbers
+ bool _eestate;
+ bool _period;
+ bool _neg_sign;
+ QString _str_int;
+ QString _str_int_exp;
+ QString _str_status[NUM_STATUS_TEXT];
+
+ QTimer* selection_timer;
+
+signals:
+ void clicked(void);
+ void changedText(QString const &);
+
+public slots:
+ void slotCut(void);
+ void slotCopy(void);
+ void slotPaste(bool bClipboard=true);
+
+private slots:
+ void slotSelectionTimedOut(void);
+ void slotDisplaySelected(void);
+};
+
+#endif // _KCALCDISPLAY_H_
diff --git a/kcalc/kcalcrc.upd b/kcalc/kcalcrc.upd
new file mode 100644
index 0000000..463da95
--- /dev/null
+++ b/kcalc/kcalcrc.upd
@@ -0,0 +1,4 @@
+Id=KDE_3_2_0
+File=kcalcrc
+Group=General
+Key=style,Statistical
diff --git a/kcalc/kcalctype.h b/kcalc/kcalctype.h
new file mode 100644
index 0000000..8223e87
--- /dev/null
+++ b/kcalc/kcalctype.h
@@ -0,0 +1,135 @@
+/*
+ $Id$
+
+ KCalc, a scientific calculator for the X window system using the
+ Qt widget libraries, available at no cost at http://www.troll.no
+
+ Copyright (C) 1996 Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+ #include "../config.h"
+#endif
+
+#ifndef KCALC_TYPE_H
+#define KCALC_TYPE_H
+
+#include <limits.h>
+#include <float.h>
+#include <math.h>
+
+#if defined(HAVE_LONG_DOUBLE) && defined(HAVE_L_FUNCS)
+/* should be detected by autoconf and defined in config.h
+ Be carefull when modifying these lines. HAVE_LONG_DOUBLE
+ is used all over kcalc's sources to determine whether
+ long double of double is the fundamental data type for kcalc*/
+
+
+
+ typedef long double CALCAMNT;
+#else
+ typedef double CALCAMNT;
+#endif
+
+
+
+#if defined(HAVE_LONG_DOUBLE) && defined(HAVE_L_FUNCS)
+ #define MODF(X,Y) modfl(X,Y)
+ #define SIN(X) sinl(X)
+ #define ASIN(X) asinl(X)
+ #define SINH(X) sinhl(X)
+ #define ASINH(X) asinhl(X)
+ #define COS(X) cosl(X)
+ #define COSH(X) coshl(X)
+ #define ACOS(X) acosl(X)
+ #define ACOSH(X) acoshl(X)
+ #define TAN(X) tanl(X)
+ #define TANH(X) tanhl(X)
+ #define ATAN(X) atanl(X)
+ #define ATANH(X) atanhl(X)
+ #define EXP(X) expl(X)
+ #define POW(X,Y) powl(X,Y)
+ #define LN(X) logl(X)
+ #define LOG_TEN(X) log10l(X)
+ #define SQRT(X) sqrtl(X)
+ #define CBRT(X) cbrtl(X)
+ #define ISINF(X) isinfl(X)
+ #define STRTOD(X,Y) strtold(X,Y)
+ #define ROUND(X) roundl(X)
+ #define CALCAMNT_EPSILON LDBL_EPSILON
+#else
+ #define MODF(X,Y) modf(X,Y)
+ #define SIN(X) sin(X)
+ #define ASIN(X) asin(X)
+ #define SINH(X) sinh(X)
+ #define ASINH(X) asinh(X)
+ #define COS(X) cos(X)
+ #define COSH(X) cosh(X)
+ #define ACOS(X) acos(X)
+ #define ACOSH(X) acosh(X)
+ #define TAN(X) tan(X)
+ #define TANH(X) tanh(X)
+ #define ATAN(X) atan(X)
+ #define ATANH(X) atanh(X)
+ #define EXP(X) exp(X)
+ #define POW(X,Y) pow(X,Y)
+ #define LN(X) log(X)
+ #define LOG_TEN(X) log10(X)
+ #define SQRT(X) sqrt(X)
+ #define CBRT(X) cbrt(X)
+ #define ISINF(X) isinf(X)
+ #define STRTOD(X,Y) strtod(X,Y)
+ #define ROUND(X) round(X)
+ #define CALCAMNT_EPSILON DBL_EPSILON
+#endif
+
+#if !defined(HAVE_FUNC_ROUND) && !defined(HAVE_FUNC_ROUNDL)
+ #undef ROUND
+ #define ROUND(X) rint(X)
+#endif
+
+#undef HAVE_LONG_LONG
+#if defined(LLONG_MAX) && defined(HAVE_LONG_DOUBLE)
+#define KCALC_LONG_MIN LLONG_MIN
+#define KCALC_LONG_MAX LLONG_MAX
+#define KCALC_ULONG_MAX ULLONG_MAX
+#define KCALC_LONG long long
+#define HAVE_LONG_LONG
+#define STRTOUL strtoull
+#else
+#if defined(LONG_LONG_MAX) && defined(HAVE_LONG_DOUBLE)
+#define KCALC_LONG_MIN LONG_LONG_MIN
+#define KCALC_LONG_MAX LONG_LONG_MAX
+#define KCALC_ULONG_MAX ULONG_LONG_MAX
+#define KCALC_LONG long long
+#define HAVE_LONG_LONG
+#ifdef _HPUX_SOURCE
+#define STRTOUL strtoul
+#else
+#define STRTOUL strtoull
+#endif
+#else
+#define KCALC_LONG_MIN LONG_MIN
+#define KCALC_LONG_MAX LONG_MAX
+#define KCALC_ULONG_MAX ULONG_MAX
+#define KCALC_LONG long
+#define STRTOUL strtoul
+#endif
+#endif
+#endif
diff --git a/kcalc/kcalcui.rc b/kcalc/kcalcui.rc
new file mode 100644
index 0000000..e79c350
--- /dev/null
+++ b/kcalc/kcalcui.rc
@@ -0,0 +1,17 @@
+<!DOCTYPE kpartgui>
+<kpartgui name="kcalc" version="19">
+<MenuBar>
+ <Menu name="settings" noMerge="1"><text>&amp;Settings</text>
+ <Action name="show_science"/>
+ <Action name="show_stat"/>
+ <Action name="show_logic"/>
+ <Action name="show_constants"/>
+ <Separator/>
+ <Action name="show_all"/>
+ <Action name="hide_all"/>
+ <Separator/>
+ <Action name="options_configure_keybinding"/>
+ <Action name="options_configure"/>
+ </Menu>
+</MenuBar>
+</kpartgui>
diff --git a/kcalc/knumber/Makefile.am b/kcalc/knumber/Makefile.am
new file mode 100644
index 0000000..6e5673b
--- /dev/null
+++ b/kcalc/knumber/Makefile.am
@@ -0,0 +1,16 @@
+AM_CPPFLAGS=-D_GNU_SOURCE -D_ISOC99_SOURCE $(all_includes)
+
+SUBDIRS = tests
+
+bin_PROGRAMS =
+lib_LTLIBRARIES =
+noinst_LTLIBRARIES = libknumber.la
+
+libknumber_la_SOURCES = knumber.cpp knumber_priv.cpp
+libknumber_la_LIBADD = $(LIBGMP) -lm
+
+METASOURCES = AUTO
+
+noinst_HEADERS = knumber.h knumber_priv.h
+
+include ../../admin/Doxyfile.am
diff --git a/kcalc/knumber/configure.in.in b/kcalc/knumber/configure.in.in
new file mode 100644
index 0000000..8ef670b
--- /dev/null
+++ b/kcalc/knumber/configure.in.in
@@ -0,0 +1,73 @@
+AC_DEFUN([KDE_C_LONG_DOUBLE],
+[
+ AC_CACHE_CHECK(for long double, ac_cv_c_long_double,
+ [
+ ac_save_LIBS="$LIBS"
+ LIBS="-lm $LIBS"
+ AC_TRY_RUN(
+ [
+#define _ISOC99_SOURCE 1
+#define _GNU_SOURCE 1
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+int main() {
+/* The Stardent Vistra knows sizeof(long double), but does not support it. */
+long double foo = 1.0;
+char buffer[10];
+/* On Ultrix 4.3 cc, long double is 4 and double is 8. */
+int result = (sizeof(long double) <= sizeof(double));
+/* the following is needed for a broken printf in glibc2 */
+if (!result) {
+ foo = foo * 3;
+ sprintf(buffer,"%0.0Lf",foo);
+ result = strcmp(buffer, "3");
+/* and now something mean ;-) */
+ foo = powl(fabsl(foo), 1);
+}
+exit(result); }
+ ],
+ ac_cv_c_long_double=yes, ac_cv_c_long_double=no,
+ ac_cv_c_long_double=no
+ )
+ LIBS="$ac_save_LIBS"
+ ])
+ if test $ac_cv_c_long_double = yes; then
+ AC_DEFINE(HAVE_LONG_DOUBLE, 1, [Define if you have support for long double in printf])
+ fi
+])
+KDE_C_LONG_DOUBLE
+
+have_l_funcs=yes
+AC_CHECK_LIB(m, sqrtl,,have_l_funcs=no)
+
+if test "xyes" = "x$have_l_funcs" ; then
+ AC_DEFINE(HAVE_L_FUNCS,1,[Define if you have *l math functions (absl, ...)])
+fi
+
+LIBGMP=
+KDE_CHECK_HEADER([gmp.h], [
+ AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+
+ kde_save_LIBS=$LIBS
+ LIBS="$all_libraries -lgmp"
+ AC_TRY_LINK(dnl
+ [
+ #include <gmp.h>
+ ],
+ [
+ mpz_t _mpz;
+ mpz_init_set_si(_mpz, 0);
+ ],
+ [LIBGMP="-lgmp"],
+ [
+ DO_NOT_COMPILE="$DO_NOT_COMPILE kcalc"
+ ])
+ LIBS=$kde_save_LIBS
+ AC_LANG_RESTORE
+
+])
+AC_SUBST(LIBGMP)
diff --git a/kcalc/knumber/knumber.cpp b/kcalc/knumber/knumber.cpp
new file mode 100644
index 0000000..d282b26
--- /dev/null
+++ b/kcalc/knumber/knumber.cpp
@@ -0,0 +1,693 @@
+// -*- c-basic-offset: 2 -*-
+/* This file is part of the KDE libraries
+ Copyright (c) 2005 Klaus Niederkrueger <kniederk@math.uni-koeln.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <math.h>
+
+#include <config.h>
+
+#include <qregexp.h>
+#include <qstring.h>
+
+#include "knumber.h"
+
+KNumber const KNumber::Zero(0);
+KNumber const KNumber::One(1);
+KNumber const KNumber::MinusOne(-1);
+KNumber const KNumber::Pi("3.141592653589793238462643383279502884197169"
+ "39937510582097494459230781640628620899862803"
+ "4825342117068");
+KNumber const KNumber::Euler("2.718281828459045235360287471352662497757"
+ "24709369995957496696762772407663035354759"
+ "4571382178525166427");
+KNumber const KNumber::NotDefined("nan");
+
+bool KNumber::_float_output = false;
+bool KNumber::_fraction_input = false;
+bool KNumber::_splitoffinteger_output = false;
+
+KNumber::KNumber(signed int num)
+{
+ _num = new _knuminteger(num);
+}
+
+KNumber::KNumber(unsigned int num)
+{
+ _num = new _knuminteger(num);
+}
+
+KNumber::KNumber(signed long int num)
+{
+ _num = new _knuminteger(num);
+}
+
+KNumber::KNumber(unsigned long int num)
+{
+ _num = new _knuminteger(num);
+}
+
+KNumber::KNumber(unsigned long long int num)
+{
+ _num = new _knuminteger(num);
+}
+
+KNumber::KNumber(double num)
+{
+ if ( isinf(num) ) _num = new _knumerror( _knumber::Infinity );
+ else if ( isnan(num) ) _num = new _knumerror( _knumber::UndefinedNumber );
+ else _num = new _knumfloat(num);
+
+}
+
+KNumber::KNumber(KNumber const & num)
+{
+ switch(num.type()) {
+ case SpecialType:
+ _num = new _knumerror(*(num._num));
+ return;
+ case IntegerType:
+ _num = new _knuminteger(*(num._num));
+ return;
+ case FractionType:
+ _num = new _knumfraction(*(num._num));
+ return;
+ case FloatType:
+ _num = new _knumfloat(*(num._num));
+ return;
+ };
+}
+
+
+KNumber::KNumber(QString const & num)
+{
+ if (QRegExp("^(inf|-inf|nan)$").exactMatch(num))
+ _num = new _knumerror(num);
+ else if (QRegExp("^[+-]?\\d+$").exactMatch(num))
+ _num = new _knuminteger(num);
+ else if (QRegExp("^[+-]?\\d+/\\d+$").exactMatch(num)) {
+ _num = new _knumfraction(num);
+ simplifyRational();
+ }
+ else if (QRegExp("^[+-]?\\d+(\\.\\d*)?(e[+-]?\\d+)?$").exactMatch(num))
+ if (_fraction_input == true) {
+ _num = new _knumfraction(num);
+ simplifyRational();
+ } else
+ _num = new _knumfloat(num);
+ else
+ _num = new _knumerror("nan");
+}
+
+KNumber::NumType KNumber::type(void) const
+{
+ if(dynamic_cast<_knumerror *>(_num))
+ return SpecialType;
+ if(dynamic_cast<_knuminteger *>(_num))
+ return IntegerType;
+ if(dynamic_cast<_knumfraction *>(_num))
+ return FractionType;
+ if(dynamic_cast<_knumfloat *>(_num))
+ return FloatType;
+
+ return SpecialType;
+}
+
+// This method converts a fraction to an integer, whenever possible,
+// i.e. 5/1 --> 5
+// This method should be called, whenever such a inproper fraction can occur,
+// e.g. when adding 4/3 + 2/3....
+void KNumber::simplifyRational(void)
+{
+ if (type() != FractionType)
+ return;
+
+ _knumfraction *tmp_num = dynamic_cast<_knumfraction *>(_num);
+
+ if (tmp_num->isInteger()) {
+ _knumber *tmp_num2 = tmp_num->intPart();
+ delete tmp_num;
+ _num = tmp_num2;
+ }
+
+}
+
+
+KNumber const & KNumber::operator=(KNumber const & num)
+{
+ if (this == & num)
+ return *this;
+
+ delete _num;
+
+ switch(num.type()) {
+ case SpecialType:
+ _num = new _knumerror();
+ break;
+ case IntegerType:
+ _num = new _knuminteger();
+ break;
+ case FractionType:
+ _num = new _knumfraction();
+ break;
+ case FloatType:
+ _num = new _knumfloat();
+ break;
+ };
+
+ _num->copy(*(num._num));
+
+ return *this;
+}
+
+KNumber & KNumber::operator +=(KNumber const &arg)
+{
+ KNumber tmp_num = *this + arg;
+
+ delete _num;
+
+ switch(tmp_num.type()) {
+ case SpecialType:
+ _num = new _knumerror();
+ break;
+ case IntegerType:
+ _num = new _knuminteger();
+ break;
+ case FractionType:
+ _num = new _knumfraction();
+ break;
+ case FloatType:
+ _num = new _knumfloat();
+ break;
+ };
+
+ _num->copy(*(tmp_num._num));
+
+ return *this;
+}
+
+KNumber & KNumber::operator -=(KNumber const &arg)
+{
+ KNumber tmp_num = *this - arg;
+
+ delete _num;
+
+ switch(tmp_num.type()) {
+ case SpecialType:
+ _num = new _knumerror();
+ break;
+ case IntegerType:
+ _num = new _knuminteger();
+ break;
+ case FractionType:
+ _num = new _knumfraction();
+ break;
+ case FloatType:
+ _num = new _knumfloat();
+ break;
+ };
+
+ _num->copy(*(tmp_num._num));
+
+ return *this;
+}
+
+// increase the digit at 'position' by one
+static void _inc_by_one(QString &str, int position)
+{
+ for (int i = position; i >= 0; i--)
+ {
+ char last_char = str[i].latin1();
+ switch(last_char)
+ {
+ case '0':
+ str[i] = '1';
+ break;
+ case '1':
+ str[i] = '2';
+ break;
+ case '2':
+ str[i] = '3';
+ break;
+ case '3':
+ str[i] = '4';
+ break;
+ case '4':
+ str[i] = '5';
+ break;
+ case '5':
+ str[i] = '6';
+ break;
+ case '6':
+ str[i] = '7';
+ break;
+ case '7':
+ str[i] = '8';
+ break;
+ case '8':
+ str[i] = '9';
+ break;
+ case '9':
+ str[i] = '0';
+ if (i == 0) str.prepend('1');
+ continue;
+ case '.':
+ continue;
+ }
+ break;
+ }
+}
+
+// Cut off if more digits in fractional part than 'precision'
+static void _round(QString &str, int precision)
+{
+ int decimalSymbolPos = str.find('.');
+
+ if (decimalSymbolPos == -1)
+ if (precision == 0) return;
+ else if (precision > 0) // add dot if missing (and needed)
+ {
+ str.append('.');
+ decimalSymbolPos = str.length() - 1;
+ }
+
+ // fill up with more than enough zeroes (in case fractional part too short)
+ str.append(QString().fill('0', precision));
+
+ // Now decide whether to round up or down
+ char last_char = str[decimalSymbolPos + precision + 1].latin1();
+ switch (last_char)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ // nothing to do, rounding down
+ break;
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ // rounding up
+ _inc_by_one(str, decimalSymbolPos + precision);
+ break;
+ default:
+ break;
+ }
+
+ decimalSymbolPos = str.find('.');
+ str.truncate(decimalSymbolPos + precision + 1);
+
+ // if precision == 0 delete also '.'
+ if (precision == 0) str = str.section('.', 0, 0);
+}
+
+static QString roundNumber(const QString &numStr, int precision)
+{
+ QString tmpString = numStr;
+ if (precision < 0 ||
+ ! QRegExp("^[+-]?\\d+(\\.\\d+)*(e[+-]?\\d+)?$").exactMatch(tmpString))
+ return numStr;
+
+
+ // Skip the sign (for now)
+ bool neg = (tmpString[0] == '-');
+ if (neg || tmpString[0] == '+') tmpString.remove(0, 1);
+
+
+ // Split off exponential part (including 'e'-symbol)
+ QString mantString = tmpString.section('e', 0, 0,
+ QString::SectionCaseInsensitiveSeps);
+ QString expString = tmpString.section('e', 1, 1,
+ QString::SectionCaseInsensitiveSeps |
+ QString::SectionIncludeLeadingSep);
+ if (expString.length() == 1) expString = QString();
+
+
+ _round(mantString, precision);
+
+ if(neg) mantString.prepend('-');
+
+ return mantString + expString;
+}
+
+
+QString const KNumber::toQString(int width, int prec) const
+{
+ QString tmp_str;
+
+ if (*this == Zero) // important to avoid infinite loops below
+ return "0";
+ switch (type()) {
+ case IntegerType:
+ if (width > 0) { //result needs to be cut-off
+ bool tmp_bool = _fraction_input; // stupid work-around
+ _fraction_input = false;
+ tmp_str = (KNumber("1.0")*(*this)).toQString(width, -1);
+ _fraction_input = tmp_bool;
+ } else
+ tmp_str = QString(_num->ascii());
+ break;
+ case FractionType:
+ if (_float_output) {
+ bool tmp_bool = _fraction_input; // stupid work-around
+ _fraction_input = false;
+ tmp_str = (KNumber("1.0")*(*this)).toQString(width, -1);
+ _fraction_input = tmp_bool;
+ } else { // _float_output == false
+ if(_splitoffinteger_output) {
+ // split off integer part
+ KNumber int_part = this->integerPart();
+ if (int_part == Zero)
+ tmp_str = QString(_num->ascii());
+ else if (int_part < Zero)
+ tmp_str = int_part.toQString() + " " + (int_part - *this)._num->ascii();
+ else
+ tmp_str = int_part.toQString() + " " + (*this - int_part)._num->ascii();
+ } else
+ tmp_str = QString(_num->ascii());
+
+ if (width > 0 && tmp_str.length() > width) {
+ //result needs to be cut-off
+ bool tmp_bool = _fraction_input; // stupid work-around
+ _fraction_input = false;
+ tmp_str = (KNumber("1.0")*(*this)).toQString(width, -1);
+ _fraction_input = tmp_bool;
+ }
+ }
+
+ break;
+ case FloatType:
+ if (width > 0)
+ tmp_str = QString(_num->ascii(width));
+ else
+ // rough estimate for maximal decimal precision (10^3 = 2^10)
+ tmp_str = QString(_num->ascii(3*mpf_get_default_prec()/10));
+ break;
+ default:
+ return QString(_num->ascii());
+ }
+
+ if (prec >= 0)
+ return roundNumber(tmp_str, prec);
+ else
+ return tmp_str;
+}
+
+void KNumber::setDefaultFloatOutput(bool flag)
+{
+ _float_output = flag;
+}
+
+void KNumber::setDefaultFractionalInput(bool flag)
+{
+ _fraction_input = flag;
+}
+
+void KNumber::setSplitoffIntegerForFractionOutput(bool flag)
+{
+ _splitoffinteger_output = flag;
+}
+
+void KNumber::setDefaultFloatPrecision(unsigned int prec)
+{
+ // Need to transform decimal digits into binary digits
+ unsigned long int bin_prec = static_cast<unsigned long int>
+ (double(prec) * M_LN10 / M_LN2 + 1);
+
+ mpf_set_default_prec(bin_prec);
+}
+
+KNumber const KNumber::abs(void) const
+{
+ KNumber tmp_num;
+ delete tmp_num._num;
+
+ tmp_num._num = _num->abs();
+
+ return tmp_num;
+}
+
+KNumber const KNumber::cbrt(void) const
+{
+ KNumber tmp_num;
+ delete tmp_num._num;
+
+ tmp_num._num = _num->cbrt();
+
+ return tmp_num;
+}
+
+KNumber const KNumber::sqrt(void) const
+{
+ KNumber tmp_num;
+ delete tmp_num._num;
+
+ tmp_num._num = _num->sqrt();
+
+ return tmp_num;
+}
+
+KNumber const KNumber::integerPart(void) const
+{
+ KNumber tmp_num;
+ delete tmp_num._num;
+ tmp_num._num = _num->intPart();
+
+ return tmp_num;
+}
+
+KNumber const KNumber::power(KNumber const &exp) const
+{
+ if (*this == Zero) {
+ if(exp == Zero)
+ return KNumber("nan"); // 0^0 not defined
+ else if (exp < Zero)
+ return KNumber("inf");
+ else
+ return KNumber(0);
+ }
+
+ if (exp == Zero) {
+ if (*this != Zero)
+ return One;
+ else
+ return KNumber("nan");
+ }
+ else if (exp < Zero) {
+ KNumber tmp_num;
+ KNumber tmp_num2 = -exp;
+ delete tmp_num._num;
+ tmp_num._num = _num->power(*(tmp_num2._num));
+
+ return One/tmp_num;
+ }
+ else {
+ KNumber tmp_num;
+ delete tmp_num._num;
+ tmp_num._num = _num->power(*(exp._num));
+
+ return tmp_num;
+ }
+
+}
+
+KNumber const KNumber::operator-(void) const
+{
+ KNumber tmp_num;
+ delete tmp_num._num;
+
+ tmp_num._num = _num->change_sign();
+
+ return tmp_num;
+}
+
+KNumber const KNumber::operator+(KNumber const & arg2) const
+{
+ KNumber tmp_num;
+ delete tmp_num._num;
+
+ tmp_num._num = _num->add(*arg2._num);
+
+ tmp_num.simplifyRational();
+
+ return tmp_num;
+}
+
+KNumber const KNumber::operator-(KNumber const & arg2) const
+{
+ return *this + (-arg2);
+}
+
+KNumber const KNumber::operator*(KNumber const & arg2) const
+{
+ KNumber tmp_num;
+ delete tmp_num._num;
+
+ tmp_num._num = _num->multiply(*arg2._num);
+
+ tmp_num.simplifyRational();
+
+ return tmp_num;
+}
+
+KNumber const KNumber::operator/(KNumber const & arg2) const
+{
+ KNumber tmp_num;
+ delete tmp_num._num;
+
+ tmp_num._num = _num->divide(*arg2._num);
+
+ tmp_num.simplifyRational();
+
+ return tmp_num;
+}
+
+
+KNumber const KNumber::operator%(KNumber const & arg2) const
+{
+ if (type() != IntegerType || arg2.type() != IntegerType)
+ return Zero;
+
+ KNumber tmp_num;
+ delete tmp_num._num;
+
+ _knuminteger const *tmp_arg1 = dynamic_cast<_knuminteger const *>(_num);
+ _knuminteger const *tmp_arg2 = dynamic_cast<_knuminteger const *>(arg2._num);
+
+ tmp_num._num = tmp_arg1->mod(*tmp_arg2);
+
+ return tmp_num;
+}
+
+KNumber const KNumber::operator&(KNumber const & arg2) const
+{
+ if (type() != IntegerType || arg2.type() != IntegerType)
+ return Zero;
+
+ KNumber tmp_num;
+ delete tmp_num._num;
+
+ _knuminteger const *tmp_arg1 = dynamic_cast<_knuminteger const *>(_num);
+ _knuminteger const *tmp_arg2 = dynamic_cast<_knuminteger const *>(arg2._num);
+
+ tmp_num._num = tmp_arg1->intAnd(*tmp_arg2);
+
+ return tmp_num;
+
+}
+
+KNumber const KNumber::operator|(KNumber const & arg2) const
+{
+ if (type() != IntegerType || arg2.type() != IntegerType)
+ return Zero;
+
+ KNumber tmp_num;
+ delete tmp_num._num;
+
+ _knuminteger const *tmp_arg1 = dynamic_cast<_knuminteger const *>(_num);
+ _knuminteger const *tmp_arg2 = dynamic_cast<_knuminteger const *>(arg2._num);
+
+ tmp_num._num = tmp_arg1->intOr(*tmp_arg2);
+
+ return tmp_num;
+}
+
+
+KNumber const KNumber::operator<<(KNumber const & arg2) const
+{
+ if (type() != IntegerType || arg2.type() != IntegerType)
+ return KNumber("nan");
+
+ _knuminteger const *tmp_arg1 = dynamic_cast<_knuminteger const *>(_num);
+ _knuminteger const *tmp_arg2 = dynamic_cast<_knuminteger const *>(arg2._num);
+
+ KNumber tmp_num;
+ delete tmp_num._num;
+ tmp_num._num = tmp_arg1->shift(*tmp_arg2);
+
+ return tmp_num;
+}
+
+KNumber const KNumber::operator>>(KNumber const & arg2) const
+{
+ if (type() != IntegerType || arg2.type() != IntegerType)
+ return KNumber("nan");
+
+ KNumber tmp_num = -arg2;
+
+ _knuminteger const *tmp_arg1 = dynamic_cast<_knuminteger const *>(_num);
+ _knuminteger const *tmp_arg2 = dynamic_cast<_knuminteger const *>(tmp_num._num);
+
+ KNumber tmp_num2;
+ delete tmp_num2._num;
+ tmp_num2._num = tmp_arg1->shift(*tmp_arg2);
+
+ return tmp_num2;
+}
+
+
+
+KNumber::operator bool(void) const
+{
+ if (*this == Zero)
+ return false;
+ return true;
+}
+
+KNumber::operator signed long int(void) const
+{
+ return static_cast<signed long int>(*_num);
+}
+
+KNumber::operator unsigned long int(void) const
+{
+ return static_cast<unsigned long int>(*_num);
+}
+
+KNumber::operator unsigned long long int(void) const
+{
+#if SIZEOF_UNSIGNED_LONG == 8
+ return static_cast<unsigned long int>(*this);
+#elif SIZEOF_UNSIGNED_LONG == 4
+ KNumber tmp_num1 = this->abs().integerPart();
+ unsigned long long int tmp_num2 = static_cast<unsigned long int>(tmp_num1) +
+ (static_cast<unsigned long long int>(
+ static_cast<unsigned long int>(tmp_num1 >> KNumber("32"))) << 32) ;
+
+#warning the cast operator from KNumber to unsigned long long int is probably buggy, when a sign is involved
+ if (*this > KNumber(0))
+ return tmp_num2;
+ else
+ return static_cast<unsigned long long int> (- static_cast<signed long long int>(tmp_num2));
+#else
+#error "SIZEOF_UNSIGNED_LONG is a unhandled case"
+#endif
+}
+
+KNumber::operator double(void) const
+{
+ return static_cast<double>(*_num);
+}
+
+int const KNumber::compare(KNumber const & arg2) const
+{
+ return _num->compare(*arg2._num);
+}
diff --git a/kcalc/knumber/knumber.h b/kcalc/knumber/knumber.h
new file mode 100644
index 0000000..489a579
--- /dev/null
+++ b/kcalc/knumber/knumber.h
@@ -0,0 +1,289 @@
+// -*- c-basic-offset: 2 -*-
+/* This file is part of the KDE libraries
+ Copyright (C) 2005 Klaus Niederkrueger <kniederk@math.uni-koeln.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef _KNUMBER_H
+#define _KNUMBER_H
+
+#include <kdelibs_export.h>
+
+#include "knumber_priv.h"
+
+class QString;
+
+/**
+ *
+ * @short Class that provides arbitrary precision numbers
+ *
+ * KNumber provides access to arbitrary precision numbers from within
+ * KDE.
+ *
+ * KNumber is based on the GMP (GNU Multiprecision) library and
+ * provides transparent support to integer, fractional and floating
+ * point number. It contains rudimentary error handling, and also
+ * includes methods for converting the numbers to QStrings for
+ * output, and to read QStrings to obtain a KNumber.
+ *
+ * The different types of numbers that can be represented by objects
+ * of this class will be described below:
+ *
+ * @li @p NumType::SpecialType - This type represents an error that
+ * has occurred, e.g. trying to divide 1 by 0 gives an object that
+ * represents infinity.
+ *
+ * @li @p NumType::IntegerType - The number is an integer. It can be
+ * arbitrarily large (restricted by the memory of the system).
+ *
+ * @li @p NumType::FractionType - A fraction is a number of the form
+ * denominator divided by nominator, where both denominator and
+ * nominator are integers of arbitrary size.
+ *
+ * @li @p NumType::FloatType - The number is of floating point
+ * type. These numbers are usually rounded, so that they do not
+ * represent precise values.
+ *
+ *
+ * @author Klaus Niederkrueger <kniederk@math.uni-koeln.de>
+ */
+class KDE_EXPORT KNumber
+{
+ public:
+ static KNumber const Zero;
+ static KNumber const One;
+ static KNumber const MinusOne;
+ static KNumber const Pi;
+ static KNumber const Euler;
+ static KNumber const NotDefined;
+
+ /**
+ * KNumber tries to provide transparent access to the following type
+ * of numbers:
+ *
+ * @li @p NumType::SpecialType - Some type of error has occurred,
+ * further inspection with @p KNumber::ErrorType
+ *
+ * @li @p NumType::IntegerType - the number is an integer
+ *
+ * @li @p NumType::FractionType - the number is a fraction
+ *
+ * @li @p NumType::FloatType - the number is of floating point type
+ *
+ */
+ enum NumType {SpecialType, IntegerType, FractionType, FloatType};
+
+ /**
+ * A KNumber that represents an error, i.e. that is of type @p
+ * NumType::SpecialType can further distinguished:
+ *
+ * @li @p ErrorType::UndefinedNumber - This is e.g. the result of
+ * taking the square root of a negative number or computing
+ * \f$ \infty - \infty \f$.
+ *
+ * @li @p ErrorType::Infinity - Such a number can be e.g. obtained
+ * by dividing 1 by 0. Some further calculations are still allowed,
+ * e.g. \f$ \infty + 5 \f$ still gives \f$\infty\f$.
+ *
+ * @li @p ErrorType::MinusInfinity - MinusInfinity behaves similarly
+ * to infinity above. It can be obtained by changing the sign of
+ * infinity.
+ *
+ */
+ enum ErrorType {UndefinedNumber, Infinity, MinusInfinity};
+
+ KNumber(signed int num = 0);
+ KNumber(unsigned int num);
+ KNumber(signed long int num);
+ KNumber(unsigned long int num);
+ KNumber(unsigned long long int num);
+
+ KNumber(double num);
+
+ KNumber(KNumber const & num);
+
+ KNumber(QString const & num);
+
+ ~KNumber()
+ {
+ delete _num;
+ }
+
+ KNumber const & operator=(KNumber const & num);
+
+ /**
+ * Returns the type of the number, as explained in @p KNumber::NumType.
+ */
+ NumType type(void) const;
+
+ /**
+ * Set whether the output of numbers (with KNumber::toQString)
+ * should happen as floating point numbers or not. This method has
+ * in fact only an effect on numbers of type @p
+ * NumType::FractionType, which can be either displayed as fractions
+ * or in decimal notation.
+ *
+ * The default behavior is not to display fractions in floating
+ * point notation.
+ */
+ static void setDefaultFloatOutput(bool flag);
+
+ /**
+ * Set whether a number constructed from a QString should be
+ * initialized as a fraction or as a float, e.g. "1.01" would be
+ * treated as 101/100, if this flag is set to true.
+ *
+ * The default setting is false.
+ */
+ static void setDefaultFractionalInput(bool flag);
+
+ /**
+ * Set the default precision to be *at least* @p prec (decimal)
+ * digits. All subsequent initialized floats will use at least this
+ * precision, but previously initialized variables are unaffected.
+ */
+ static void setDefaultFloatPrecision(unsigned int prec);
+
+ /**
+ * What a terrible method name!! When displaying a fraction, the
+ * default mode gives @p "nomin/denom". With this method one can
+ * choose to display a fraction as @p "integer nomin/denom".
+ *
+ * Examples: Default representation mode is 47/17, but if @p flag is
+ * @p true, then the result is 2 13/17.
+ */
+ static void setSplitoffIntegerForFractionOutput(bool flag);
+
+ /**
+ * Return a QString representing the KNumber.
+ *
+ * @param width This number specifies the maximal length of the
+ * output, before the method switches to exponential notation and
+ * does rounding. For negative numbers, this option is ignored.
+ *
+ * @param prec This parameter controls the number of digits
+ * following the decimal point. For negative numbers, this option
+ * is ignored.
+ *
+ */
+ QString const toQString(int width = -1, int prec = -1) const;
+
+ /**
+ * Compute the absolute value, i.e. @p x.abs() returns the value
+ *
+ * \f[ \left\{\begin{array}{cl} x, & x \ge 0 \\ -x, & x <
+ * 0\end{array}\right.\f]
+ * This method works for \f$ x = \infty \f$ and \f$ x = -\infty \f$.
+ */
+ KNumber const abs(void) const;
+
+ /**
+ * Compute the square root. If \f$ x < 0 \f$ (including \f$
+ * x=-\infty \f$), then @p x.sqrt() returns @p
+ * ErrorType::UndefinedNumber.
+ *
+ * If @p x is an integer or a fraction, then @p x.sqrt() tries to
+ * compute the exact square root. If the square root is not a
+ * fraction, then a float with the default precision is returned.
+ *
+ * This method works for \f$ x = \infty \f$ giving \f$ \infty \f$.
+ */
+ KNumber const sqrt(void) const;
+
+ /**
+ * Compute the cube root.
+ *
+ * If @p x is an integer or a fraction, then @p x.cbrt() tries to
+ * compute the exact cube root. If the cube root is not a fraction,
+ * then a float is returned, but
+ *
+ * WARNING: A float cube root is computed as a standard @p double
+ * that is later transformed back into a @p KNumber.
+ *
+ * This method works for \f$ x = \infty \f$ giving \f$ \infty \f$,
+ * and for \f$ x = -\infty \f$ giving \f$ -\infty \f$.
+ */
+ KNumber const cbrt(void) const;
+
+ /**
+ * Truncates a @p KNumber to its integer type returning a number of
+ * type @p NumType::IntegerType.
+ *
+ * If \f$ x = \pm\infty \f$, integerPart leaves the value unchanged,
+ * i.e. it returns \f$ \pm\infty \f$.
+ */
+ KNumber const integerPart(void) const;
+
+ KNumber const power(KNumber const &exp) const;
+
+ KNumber const operator+(KNumber const & arg2) const;
+ KNumber const operator -(void) const;
+ KNumber const operator-(KNumber const & arg2) const;
+ KNumber const operator*(KNumber const & arg2) const;
+ KNumber const operator/(KNumber const & arg2) const;
+ KNumber const operator%(KNumber const & arg2) const;
+
+ KNumber const operator&(KNumber const & arg2) const;
+ KNumber const operator|(KNumber const & arg2) const;
+ KNumber const operator<<(KNumber const & arg2) const;
+ KNumber const operator>>(KNumber const & arg2) const;
+
+ operator bool(void) const;
+ operator signed long int(void) const;
+ operator unsigned long int(void) const;
+ operator unsigned long long int(void) const;
+ operator double(void) const;
+
+ bool const operator==(KNumber const & arg2) const
+ { return (compare(arg2) == 0); }
+
+ bool const operator!=(KNumber const & arg2) const
+ { return (compare(arg2) != 0); }
+
+ bool const operator>(KNumber const & arg2) const
+ { return (compare(arg2) > 0); }
+
+ bool const operator<(KNumber const & arg2) const
+ { return (compare(arg2) < 0); }
+
+ bool const operator>=(KNumber const & arg2) const
+ { return (compare(arg2) >= 0); }
+
+ bool const operator<=(KNumber const & arg2) const
+ { return (compare(arg2) <= 0); }
+
+ KNumber & operator +=(KNumber const &arg);
+ KNumber & operator -=(KNumber const &arg);
+
+
+ //KNumber const toFloat(void) const;
+
+
+
+
+ private:
+ void simplifyRational(void);
+ int const compare(KNumber const & arg2) const;
+
+ _knumber *_num;
+ static bool _float_output;
+ static bool _fraction_input;
+ static bool _splitoffinteger_output;
+};
+
+
+
+#endif // _KNUMBER_H
diff --git a/kcalc/knumber/knumber_priv.cpp b/kcalc/knumber/knumber_priv.cpp
new file mode 100644
index 0000000..1326d44
--- /dev/null
+++ b/kcalc/knumber/knumber_priv.cpp
@@ -0,0 +1,1083 @@
+/* This file is part of the KDE libraries
+ Copyright (c) 2005 Klaus Niederkrueger <kniederk@math.uni-koeln.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include <math.h>
+#include <config.h>
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <qregexp.h>
+#include <qstring.h>
+
+#include "knumber_priv.h"
+
+_knumerror::_knumerror(_knumber const & num)
+{
+ switch(num.type()) {
+ case SpecialType:
+ _error = dynamic_cast<_knumerror const &>(num)._error;
+ break;
+ case IntegerType:
+ case FractionType:
+ case FloatType:
+ // What should I do here?
+ break;
+ }
+}
+
+
+
+_knuminteger::_knuminteger(unsigned long long int num)
+{
+ mpz_init(_mpz);
+#if SIZEOF_UNSIGNED_LONG == 8
+ mpz_init_set_ui(_mpz, static_cast<unsigned long int>(num));
+#elif SIZEOF_UNSIGNED_LONG == 4
+ mpz_set_ui(_mpz, static_cast<unsigned long int>(num >> 32));
+ mpz_mul_2exp(_mpz, _mpz, 32);
+ mpz_add_ui(_mpz, _mpz, static_cast<unsigned long int>(num));
+#else
+#error "SIZEOF_UNSIGNED_LONG is a unhandled case"
+#endif
+}
+
+
+_knuminteger::_knuminteger(_knumber const & num)
+{
+ mpz_init(_mpz);
+
+ switch(num.type()) {
+ case IntegerType:
+ mpz_set(_mpz, dynamic_cast<_knuminteger const &>(num)._mpz);
+ break;
+ case FractionType:
+ case FloatType:
+ case SpecialType:
+ // What should I do here?
+ break;
+ }
+}
+
+_knumfraction::_knumfraction(_knumber const & num)
+{
+ mpq_init(_mpq);
+
+ switch(num.type()) {
+ case IntegerType:
+ mpq_set_z(_mpq, dynamic_cast<_knuminteger const &>(num)._mpz);
+ break;
+ case FractionType:
+ mpq_set(_mpq, dynamic_cast<_knumfraction const &>(num)._mpq);
+ break;
+ case FloatType:
+ case SpecialType:
+ // What should I do here?
+ break;
+ }
+}
+
+_knumfloat::_knumfloat(_knumber const & num)
+{
+ mpf_init(_mpf);
+
+ switch(num.type()) {
+ case IntegerType:
+ mpf_set_z(_mpf, dynamic_cast<_knuminteger const &>(num)._mpz);
+ break;
+ case FractionType:
+ mpf_set_q(_mpf, dynamic_cast<_knumfraction const &>(num)._mpq);
+ break;
+ case FloatType:
+ mpf_set(_mpf, dynamic_cast<_knumfloat const &>(num)._mpf);
+ break;
+ case SpecialType:
+ // What should I do here?
+ break;
+ }
+}
+
+
+
+_knumerror::_knumerror(QString const & num)
+{
+ if (num == "nan")
+ _error = UndefinedNumber;
+ else if (num == "inf")
+ _error = Infinity;
+ else if (num == "-inf")
+ _error = MinusInfinity;
+}
+
+_knuminteger::_knuminteger(QString const & num)
+{
+ mpz_init(_mpz);
+ mpz_set_str(_mpz, num.ascii(), 10);
+}
+
+_knumfraction::_knumfraction(QString const & num)
+{
+ mpq_init(_mpq);
+ if (QRegExp("^[+-]?\\d+(\\.\\d*)?(e[+-]?\\d+)?$").exactMatch(num)) {
+ // my hand-made conversion is terrible
+ // first me convert the mantissa
+ unsigned long int digits_after_dot = ((num.section( '.', 1, 1)).section('e', 0, 0)).length();
+ QString tmp_num = num.section('e', 0, 0).remove('.');
+ mpq_set_str(_mpq, tmp_num.ascii(), 10);
+ mpz_t tmp_int;
+ mpz_init(tmp_int);
+ mpz_ui_pow_ui (tmp_int, 10, digits_after_dot);
+ mpz_mul(mpq_denref(_mpq), mpq_denref(_mpq), tmp_int);
+ // now we take care of the exponent
+ if (! (tmp_num = num.section('e', 1, 1)).isEmpty()) {
+ long int tmp_exp = tmp_num.toLong();
+ if (tmp_exp > 0) {
+ mpz_ui_pow_ui (tmp_int, 10,
+ static_cast<unsigned long int>(tmp_exp));
+ mpz_mul(mpq_numref(_mpq), mpq_numref(_mpq), tmp_int);
+ } else {
+ mpz_ui_pow_ui (tmp_int, 10,
+ static_cast<unsigned long int>(-tmp_exp));
+ mpz_mul(mpq_denref(_mpq), mpq_denref(_mpq), tmp_int);
+ }
+ }
+ mpz_clear(tmp_int);
+ } else
+ mpq_set_str(_mpq, num.ascii(), 10);
+ mpq_canonicalize(_mpq);
+}
+
+_knumfloat::_knumfloat(QString const & num)
+{
+ mpf_init(_mpf);
+ mpf_set_str(_mpf, num.ascii(), 10);
+}
+
+_knuminteger const & _knuminteger::operator = (_knuminteger const & num)
+{
+ if (this == &num)
+ return *this;
+
+ mpz_set(_mpz, num._mpz);
+ return *this;
+}
+
+QString const _knumerror::ascii(int prec) const
+{
+ static_cast<void>(prec);
+
+ switch(_error) {
+ case UndefinedNumber:
+ return QString("nan");
+ case Infinity:
+ return QString("inf");
+ case MinusInfinity:
+ return QString("-inf");
+ default:
+ return QString::null;
+ }
+}
+
+QString const _knuminteger::ascii(int prec) const
+{
+ static_cast<void>(prec);
+ char *tmp_ptr;
+
+ gmp_asprintf(&tmp_ptr, "%Zd", _mpz);
+ QString ret_str = tmp_ptr;
+
+ free(tmp_ptr);
+ return ret_str;
+}
+
+QString const _knumfraction::ascii(int prec) const
+{
+ static_cast<void>(prec);
+ char *tmp_ptr = mpq_get_str(0, 10, _mpq);
+ QString ret_str = tmp_ptr;
+
+ free(tmp_ptr);
+
+ return ret_str;
+}
+
+QString const _knumfloat::ascii(int prec) const
+{
+ QString ret_str;
+ char *tmp_ptr;
+ if (prec > 0)
+ gmp_asprintf(&tmp_ptr, ("%." + QString().setNum(prec) + "Fg").ascii(), _mpf);
+ else
+ gmp_asprintf(&tmp_ptr, "%Fg", _mpf);
+
+ ret_str = tmp_ptr;
+
+ free(tmp_ptr);
+
+ return ret_str;
+}
+
+
+bool _knumfraction::isInteger(void) const
+{
+ if (mpz_cmp_ui(mpq_denref(_mpq), 1) == 0)
+ return true;
+ else
+ return false;
+}
+
+
+_knumber * _knumerror::abs(void) const
+{
+ _knumerror * tmp_num = new _knumerror(*this);
+
+ if(_error == MinusInfinity) tmp_num->_error = Infinity;
+
+ return tmp_num;
+}
+
+_knumber * _knuminteger::abs(void) const
+{
+ _knuminteger * tmp_num = new _knuminteger();
+
+ mpz_abs(tmp_num->_mpz, _mpz);
+
+ return tmp_num;
+}
+
+_knumber * _knumfraction::abs(void) const
+{
+ _knumfraction * tmp_num = new _knumfraction();
+
+ mpq_abs(tmp_num->_mpq, _mpq);
+
+ return tmp_num;
+}
+
+_knumber * _knumfloat::abs(void) const
+{
+ _knumfloat * tmp_num = new _knumfloat();
+
+ mpf_abs(tmp_num->_mpf, _mpf);
+
+ return tmp_num;
+}
+
+
+
+_knumber * _knumerror::intPart(void) const
+{
+ return new _knumerror(*this);
+}
+
+_knumber * _knuminteger::intPart(void) const
+{
+ _knuminteger *tmp_num = new _knuminteger();
+ mpz_set(tmp_num->_mpz, _mpz);
+ return tmp_num;
+}
+
+_knumber * _knumfraction::intPart(void) const
+{
+ _knuminteger *tmp_num = new _knuminteger();
+
+ mpz_set_q(tmp_num->_mpz, _mpq);
+
+ return tmp_num;
+}
+
+_knumber * _knumfloat::intPart(void) const
+{
+ _knuminteger *tmp_num = new _knuminteger();
+
+ mpz_set_f(tmp_num->_mpz, _mpf);
+
+ return tmp_num;
+}
+
+
+
+
+int _knumerror::sign(void) const
+{
+ switch(_error) {
+ case Infinity:
+ return 1;
+ case MinusInfinity:
+ return -1;
+ default:
+ return 0;
+ }
+}
+
+int _knuminteger::sign(void) const
+{
+ return mpz_sgn(_mpz);
+}
+
+int _knumfraction::sign(void) const
+{
+ return mpq_sgn(_mpq);
+}
+
+int _knumfloat::sign(void) const
+{
+ return mpf_sgn(_mpf);
+}
+
+
+
+#warning _cbrt for now this is a stupid work around
+static void _cbrt(mpf_t &num)
+{
+ double tmp_num = cbrt(mpf_get_d(num));
+ mpf_init_set_d(num, tmp_num);
+}
+
+
+_knumber * _knumerror::cbrt(void) const
+{
+ // infty ^3 = infty; -infty^3 = -infty
+ _knumerror *tmp_num = new _knumerror(*this);
+
+ return tmp_num;
+}
+
+_knumber * _knuminteger::cbrt(void) const
+{
+ _knuminteger * tmp_num = new _knuminteger();
+
+ if(mpz_root(tmp_num->_mpz, _mpz, 3))
+ return tmp_num; // root is perfect
+
+ delete tmp_num; // root was not perfect, result will be float
+
+ _knumfloat * tmp_num2 = new _knumfloat();
+ mpf_set_z(tmp_num2->_mpf, _mpz);
+
+ _cbrt(tmp_num2->_mpf);
+
+ return tmp_num2;
+}
+
+_knumber * _knumfraction::cbrt(void) const
+{
+ _knumfraction * tmp_num = new _knumfraction();
+ if (mpz_root(mpq_numref(tmp_num->_mpq), mpq_numref(_mpq), 3)
+ && mpz_root(mpq_denref(tmp_num->_mpq), mpq_denref(_mpq), 3))
+ return tmp_num; // root is perfect
+
+ delete tmp_num; // root was not perfect, result will be float
+
+ _knumfloat * tmp_num2 = new _knumfloat();
+ mpf_set_q(tmp_num2->_mpf, _mpq);
+
+ _cbrt(tmp_num2->_mpf);
+
+ return tmp_num2;
+}
+
+_knumber * _knumfloat::cbrt(void) const
+{
+ _knumfloat * tmp_num = new _knumfloat(*this);
+
+ _cbrt(tmp_num->_mpf);
+
+ return tmp_num;
+}
+
+
+
+
+_knumber * _knumerror::sqrt(void) const
+{
+ _knumerror *tmp_num = new _knumerror(*this);
+
+ if(_error == MinusInfinity) tmp_num->_error = UndefinedNumber;
+
+ return tmp_num;
+}
+
+_knumber * _knuminteger::sqrt(void) const
+{
+ if (mpz_sgn(_mpz) < 0) {
+ _knumerror *tmp_num = new _knumerror(UndefinedNumber);
+ return tmp_num;
+ }
+ if (mpz_perfect_square_p(_mpz)) {
+ _knuminteger * tmp_num = new _knuminteger();
+
+ mpz_sqrt(tmp_num->_mpz, _mpz);
+
+ return tmp_num;
+ } else {
+ _knumfloat * tmp_num = new _knumfloat();
+ mpf_set_z(tmp_num->_mpf, _mpz);
+ mpf_sqrt(tmp_num->_mpf, tmp_num->_mpf);
+
+ return tmp_num;
+ }
+}
+
+_knumber * _knumfraction::sqrt(void) const
+{
+ if (mpq_sgn(_mpq) < 0) {
+ _knumerror *tmp_num = new _knumerror(UndefinedNumber);
+ return tmp_num;
+ }
+ if (mpz_perfect_square_p(mpq_numref(_mpq))
+ && mpz_perfect_square_p(mpq_denref(_mpq))) {
+ _knumfraction * tmp_num = new _knumfraction();
+ mpq_set(tmp_num->_mpq, _mpq);
+ mpz_sqrt(mpq_numref(tmp_num->_mpq), mpq_numref(tmp_num->_mpq));
+ mpz_sqrt(mpq_denref(tmp_num->_mpq), mpq_denref(tmp_num->_mpq));
+
+ return tmp_num;
+ } else {
+ _knumfloat * tmp_num = new _knumfloat();
+ mpf_set_q(tmp_num->_mpf, _mpq);
+ mpf_sqrt(tmp_num->_mpf, tmp_num->_mpf);
+
+ return tmp_num;
+ }
+
+ _knumfraction * tmp_num = new _knumfraction();
+
+ return tmp_num;
+}
+
+_knumber * _knumfloat::sqrt(void) const
+{
+ if (mpf_sgn(_mpf) < 0) {
+ _knumerror *tmp_num = new _knumerror(UndefinedNumber);
+ return tmp_num;
+ }
+ _knumfloat * tmp_num = new _knumfloat();
+
+ mpf_sqrt(tmp_num->_mpf, _mpf);
+
+ return tmp_num;
+}
+
+
+
+_knumber * _knumerror::change_sign(void) const
+{
+ _knumerror * tmp_num = new _knumerror();
+
+ if(_error == Infinity) tmp_num->_error = MinusInfinity;
+ if(_error == MinusInfinity) tmp_num->_error = Infinity;
+
+ return tmp_num;
+}
+
+_knumber * _knuminteger::change_sign(void) const
+{
+ _knuminteger * tmp_num = new _knuminteger();
+
+ mpz_neg(tmp_num->_mpz, _mpz);
+
+ return tmp_num;
+}
+
+_knumber * _knumfraction::change_sign(void) const
+{
+ _knumfraction * tmp_num = new _knumfraction();
+
+ mpq_neg(tmp_num->_mpq, _mpq);
+
+ return tmp_num;
+}
+
+_knumber *_knumfloat::change_sign(void) const
+{
+ _knumfloat * tmp_num = new _knumfloat();
+
+ mpf_neg(tmp_num->_mpf, _mpf);
+
+ return tmp_num;
+}
+
+
+_knumber * _knumerror::reciprocal(void) const
+{
+ switch(_error) {
+ case Infinity:
+ case MinusInfinity:
+ return new _knuminteger(0);
+ case UndefinedNumber:
+ default:
+ return new _knumerror(UndefinedNumber);
+ }
+}
+
+_knumber * _knuminteger::reciprocal(void) const
+{
+ if(mpz_cmp_si(_mpz, 0) == 0) return new _knumerror(Infinity);
+
+ _knumfraction * tmp_num = new _knumfraction(*this);
+
+ mpq_inv(tmp_num->_mpq, tmp_num->_mpq);
+
+ return tmp_num;
+}
+
+_knumber * _knumfraction::reciprocal() const
+{
+ if(mpq_cmp_si(_mpq, 0, 1) == 0) return new _knumerror(Infinity);
+
+ _knumfraction * tmp_num = new _knumfraction();
+
+ mpq_inv(tmp_num->_mpq, _mpq);
+
+ return tmp_num;
+}
+
+_knumber *_knumfloat::reciprocal(void) const
+{
+ if(mpf_cmp_si(_mpf, 0) == 0) return new _knumerror(Infinity);
+
+ _knumfloat * tmp_num = new _knumfloat();
+
+ mpf_div(tmp_num->_mpf, _knumfloat("1.0")._mpf, _mpf);
+
+ return tmp_num;
+}
+
+
+
+_knumber * _knumerror::add(_knumber const & arg2) const
+{
+ if (arg2.type() != SpecialType)
+ return new _knumerror(_error);
+
+ _knumerror const & tmp_arg2 = dynamic_cast<_knumerror const &>(arg2);
+
+ if (_error == UndefinedNumber
+ || tmp_arg2._error == UndefinedNumber
+ || (_error == Infinity && tmp_arg2._error == MinusInfinity)
+ || (_error == MinusInfinity && tmp_arg2._error == Infinity)
+ )
+ return new _knumerror(UndefinedNumber);
+
+ return new _knumerror(_error);
+}
+
+_knumber * _knuminteger::add(_knumber const & arg2) const
+{
+ if (arg2.type() != IntegerType)
+ return arg2.add(*this);
+
+ _knuminteger * tmp_num = new _knuminteger();
+
+ mpz_add(tmp_num->_mpz, _mpz,
+ dynamic_cast<_knuminteger const &>(arg2)._mpz);
+
+ return tmp_num;
+}
+
+_knumber * _knumfraction::add(_knumber const & arg2) const
+{
+ if (arg2.type() == IntegerType) {
+ // need to cast arg2 to fraction
+ _knumfraction tmp_num(arg2);
+ return tmp_num.add(*this);
+ }
+
+
+ if (arg2.type() == FloatType || arg2.type() == SpecialType)
+ return arg2.add(*this);
+
+ _knumfraction * tmp_num = new _knumfraction();
+
+ mpq_add(tmp_num->_mpq, _mpq,
+ dynamic_cast<_knumfraction const &>(arg2)._mpq);
+
+ return tmp_num;
+}
+
+_knumber *_knumfloat::add(_knumber const & arg2) const
+{
+ if (arg2.type() == SpecialType)
+ return arg2.add(*this);
+
+ if (arg2.type() != FloatType) {
+ // need to cast arg2 to float
+ _knumfloat tmp_num(arg2);
+ return tmp_num.add(*this);
+ }
+
+ _knumfloat * tmp_num = new _knumfloat();
+
+ mpf_add(tmp_num->_mpf, _mpf,
+ dynamic_cast<_knumfloat const &>(arg2)._mpf);
+
+ return tmp_num;
+}
+
+
+_knumber * _knumerror::multiply(_knumber const & arg2) const
+{
+ //improve this
+ switch(arg2.type()) {
+ case SpecialType:
+ {
+ _knumerror const & tmp_arg2 = dynamic_cast<_knumerror const &>(arg2);
+ if (_error == UndefinedNumber || tmp_arg2._error == UndefinedNumber)
+ return new _knumerror(UndefinedNumber);
+ if ( this->sign() * arg2.sign() > 0)
+ return new _knumerror(Infinity);
+ else
+ return new _knumerror(MinusInfinity);
+ }
+ case IntegerType:
+ case FractionType:
+ case FloatType:
+ {
+ int sign_arg2 = arg2.sign();
+ if (_error == UndefinedNumber || sign_arg2 == 0)
+ return new _knumerror(UndefinedNumber);
+ if ( (_error == Infinity && sign_arg2 > 0) ||
+ (_error == MinusInfinity && sign_arg2 < 0) )
+ return new _knumerror(Infinity);
+
+ return new _knumerror(MinusInfinity);
+ }
+ }
+
+ return new _knumerror(_error);
+}
+
+
+_knumber * _knuminteger::multiply(_knumber const & arg2) const
+{
+ if (arg2.type() != IntegerType)
+ return arg2.multiply(*this);
+
+ _knuminteger * tmp_num = new _knuminteger();
+
+ mpz_mul(tmp_num->_mpz, _mpz,
+ dynamic_cast<_knuminteger const &>(arg2)._mpz);
+
+ return tmp_num;
+}
+
+_knumber * _knumfraction::multiply(_knumber const & arg2) const
+{
+ if (arg2.type() == IntegerType) {
+ // need to cast arg2 to fraction
+ _knumfraction tmp_num(arg2);
+ return tmp_num.multiply(*this);
+ }
+
+
+ if (arg2.type() == FloatType || arg2.type() == SpecialType)
+ return arg2.multiply(*this);
+
+ _knumfraction * tmp_num = new _knumfraction();
+
+ mpq_mul(tmp_num->_mpq, _mpq,
+ dynamic_cast<_knumfraction const &>(arg2)._mpq);
+
+ return tmp_num;
+}
+
+_knumber *_knumfloat::multiply(_knumber const & arg2) const
+{
+ if (arg2.type() == SpecialType)
+ return arg2.multiply(*this);
+ if (arg2.type() == IntegerType &&
+ mpz_cmp_si(dynamic_cast<_knuminteger const &>(arg2)._mpz,0) == 0)
+ // if arg2 == 0 return integer 0!!
+ return new _knuminteger(0);
+
+ if (arg2.type() != FloatType) {
+ // need to cast arg2 to float
+ _knumfloat tmp_num(arg2);
+ return tmp_num.multiply(*this);
+ }
+
+ _knumfloat * tmp_num = new _knumfloat();
+
+ mpf_mul(tmp_num->_mpf, _mpf,
+ dynamic_cast<_knumfloat const &>(arg2)._mpf);
+
+ return tmp_num;
+}
+
+
+
+
+
+_knumber * _knumber::divide(_knumber const & arg2) const
+{
+ _knumber * tmp_num = arg2.reciprocal();
+ _knumber * rslt_num = this->multiply(*tmp_num);
+
+ delete tmp_num;
+
+ return rslt_num;
+}
+
+_knumber *_knumfloat::divide(_knumber const & arg2) const
+{
+ if(mpf_cmp_si(_mpf, 0) == 0) return new _knumerror(Infinity);
+
+ // automatically casts arg2 to float
+ _knumfloat * tmp_num = new _knumfloat(arg2);
+
+ mpf_div(tmp_num->_mpf, _mpf, tmp_num->_mpf);
+
+ return tmp_num;
+}
+
+
+
+
+_knumber * _knumerror::power(_knumber const & exponent) const
+{
+ static_cast<void>(exponent);
+ return new _knumerror(UndefinedNumber);
+}
+
+_knumber * _knuminteger::power(_knumber const & exponent) const
+{
+ if (exponent.type() == IntegerType) {
+
+ mpz_t tmp_mpz;
+ mpz_init_set(tmp_mpz,
+ dynamic_cast<_knuminteger const &>(exponent)._mpz);
+
+ if (! mpz_fits_ulong_p(tmp_mpz)) { // conversion wouldn't work, so
+ // use floats
+ mpz_clear(tmp_mpz);
+ // need to cast everything to float
+ _knumfloat tmp_num1(*this), tmp_num2(exponent);
+ return tmp_num1.power(tmp_num2);
+ }
+
+ unsigned long int tmp_int = mpz_get_ui(tmp_mpz);
+ mpz_clear(tmp_mpz);
+
+ _knuminteger * tmp_num = new _knuminteger();
+ mpz_pow_ui(tmp_num->_mpz, _mpz, tmp_int);
+ return tmp_num;
+ }
+ if (exponent.type() == FractionType) {
+ if (mpz_sgn(_mpz) < 0)
+ return new _knumerror(UndefinedNumber);
+ // GMP only supports few root functions, so we need to convert
+ // into signed long int
+ mpz_t tmp_mpz;
+ mpz_init_set(tmp_mpz,
+ mpq_denref(dynamic_cast<_knumfraction const &>(exponent)._mpq));
+
+ if (! mpz_fits_ulong_p(tmp_mpz)) { // conversion wouldn't work, so
+ // use floats
+ mpz_clear(tmp_mpz);
+ // need to cast everything to float
+ _knumfloat tmp_num1(*this), tmp_num2(exponent);
+ return tmp_num1.power(tmp_num2);
+ }
+
+ unsigned long int tmp_int = mpz_get_ui(tmp_mpz);
+ mpz_clear(tmp_mpz);
+
+ // first check if result will be an integer
+ _knuminteger * tmp_num = new _knuminteger();
+ int flag = mpz_root(tmp_num->_mpz, _mpz, tmp_int);
+ if (flag == 0) { // result is not exact
+ delete tmp_num;
+ // need to cast everything to float
+ _knumfloat tmp_num1(*this), tmp_num2(exponent);
+ return tmp_num1.power(tmp_num2);
+ }
+
+ // result is exact
+
+ mpz_init_set(tmp_mpz,
+ mpq_numref(dynamic_cast<_knumfraction const &>(exponent)._mpq));
+
+ if (! mpz_fits_ulong_p(tmp_mpz)) { // conversion wouldn't work, so
+ // use floats
+ mpz_clear(tmp_mpz);
+ // need to cast everything to float
+ _knumfloat tmp_num1(*this), tmp_num2(exponent);
+ return tmp_num1.power(tmp_num2);
+ }
+ tmp_int = mpz_get_ui(tmp_mpz);
+ mpz_clear(tmp_mpz);
+
+ mpz_pow_ui(tmp_num->_mpz, tmp_num->_mpz, tmp_int);
+
+ return tmp_num;
+ }
+ if (exponent.type() == FloatType) {
+ // need to cast everything to float
+ _knumfloat tmp_num(*this);
+ return tmp_num.power(exponent);
+ }
+
+ return new _knumerror(Infinity);
+}
+
+_knumber * _knumfraction::power(_knumber const & exponent) const
+{
+ _knuminteger tmp_num = _knuminteger();
+
+ mpz_set(tmp_num._mpz, mpq_numref(_mpq));
+ _knumber *numer = tmp_num.power(exponent);
+
+ mpz_set(tmp_num._mpz, mpq_denref(_mpq));
+ _knumber *denom = tmp_num.power(exponent);
+
+ _knumber *result = numer->divide(*denom);
+ delete numer;
+ delete denom;
+ return result;
+}
+
+_knumber * _knumfloat::power(_knumber const & exponent) const
+{
+ return new _knumfloat(pow(static_cast<double>(*this),
+ static_cast<double>(exponent)));
+}
+
+
+int _knumerror::compare(_knumber const &arg2) const
+{
+ if (arg2.type() != SpecialType) {
+ switch(_error) {
+ case Infinity:
+ return 1;
+ case MinusInfinity:
+ return -1;
+ default:
+ return 1; // Not really o.k., but what should I return
+ }
+ }
+
+ switch(_error) {
+ case Infinity:
+ if (dynamic_cast<_knumerror const &>(arg2)._error == Infinity)
+ // Infinity is larger than anything else, but itself
+ return 0;
+ return 1;
+ case MinusInfinity:
+ if (dynamic_cast<_knumerror const &>(arg2)._error == MinusInfinity)
+ // MinusInfinity is smaller than anything else, but itself
+ return 0;
+ return -1;
+ default:
+ if (dynamic_cast<_knumerror const &>(arg2)._error == UndefinedNumber)
+ // Undefined only equal to itself
+ return 0;
+ return -arg2.compare(*this);
+ }
+}
+
+int _knuminteger::compare(_knumber const &arg2) const
+{
+ if (arg2.type() != IntegerType)
+ return - arg2.compare(*this);
+
+ return mpz_cmp(_mpz, dynamic_cast<_knuminteger const &>(arg2)._mpz);
+}
+
+int _knumfraction::compare(_knumber const &arg2) const
+{
+ if (arg2.type() != FractionType) {
+ if (arg2.type() == IntegerType) {
+ mpq_t tmp_frac;
+ mpq_init(tmp_frac);
+ mpq_set_z(tmp_frac,
+ dynamic_cast<_knuminteger const &>(arg2)._mpz);
+ int cmp_result = mpq_cmp(_mpq, tmp_frac);
+ mpq_clear(tmp_frac);
+ return cmp_result;
+ } else
+ return - arg2.compare(*this);
+ }
+
+ return mpq_cmp(_mpq, dynamic_cast<_knumfraction const &>(arg2)._mpq);
+}
+
+int _knumfloat::compare(_knumber const &arg2) const
+{
+ if (arg2.type() != FloatType) {
+ mpf_t tmp_float;
+ if (arg2.type() == IntegerType) {
+ mpf_init(tmp_float);
+ mpf_set_z(tmp_float,
+ dynamic_cast<_knuminteger const &>(arg2)._mpz);
+ } else if (arg2.type() == FractionType) {
+ mpf_init(tmp_float);
+ mpf_set_q(tmp_float,
+ dynamic_cast<_knumfraction const &>(arg2)._mpq);
+ } else
+ return - arg2.compare(*this);
+
+ int cmp_result = mpf_cmp(_mpf, tmp_float);
+ mpf_clear(tmp_float);
+ return cmp_result;
+ }
+
+ return mpf_cmp(_mpf, dynamic_cast<_knumfloat const &>(arg2)._mpf);
+}
+
+
+
+_knumerror::operator signed long int (void) const
+{
+ // what would be the correct return values here?
+ if (_error == Infinity)
+ return 0;
+ if (_error == MinusInfinity)
+ return 0;
+ else // if (_error == UndefinedNumber)
+ return 0;
+}
+
+_knumerror::operator unsigned long int (void) const
+{
+ // what would be the correct return values here?
+ if (_error == Infinity)
+ return 0;
+ if (_error == MinusInfinity)
+ return 0;
+ else // if (_error == UndefinedNumber)
+ return 0;
+}
+
+
+_knuminteger::operator signed long int (void) const
+{
+ return mpz_get_si(_mpz);
+}
+
+_knumfraction::operator signed long int (void) const
+{
+ return static_cast<signed long int>(mpq_get_d(_mpq));
+}
+
+_knumfloat::operator signed long int (void) const
+{
+ return mpf_get_si(_mpf);
+}
+
+_knuminteger::operator unsigned long int (void) const
+{
+ return mpz_get_ui(_mpz);
+}
+
+_knumfraction::operator unsigned long int (void) const
+{
+ return static_cast<unsigned long int>(mpq_get_d(_mpq));
+}
+
+_knumfloat::operator unsigned long int (void) const
+{
+ return mpf_get_ui(_mpf);
+}
+
+
+
+_knumerror::operator double (void) const
+{
+ if (_error == Infinity)
+ return INFINITY;
+ if (_error == MinusInfinity)
+ return -INFINITY;
+ else // if (_error == UndefinedNumber)
+ return NAN;
+}
+
+_knuminteger::operator double (void) const
+{
+ return mpz_get_d(_mpz);
+}
+
+_knumfraction::operator double (void) const
+{
+ return mpq_get_d(_mpq);
+}
+
+_knumfloat::operator double (void) const
+{
+ return mpf_get_d(_mpf);
+}
+
+
+
+
+_knuminteger * _knuminteger::intAnd(_knuminteger const &arg2) const
+{
+ _knuminteger * tmp_num = new _knuminteger();
+
+ mpz_and(tmp_num->_mpz, _mpz, arg2._mpz);
+
+ return tmp_num;
+}
+
+_knuminteger * _knuminteger::intOr(_knuminteger const &arg2) const
+{
+ _knuminteger * tmp_num = new _knuminteger();
+
+ mpz_ior(tmp_num->_mpz, _mpz, arg2._mpz);
+
+ return tmp_num;
+}
+
+_knumber * _knuminteger::mod(_knuminteger const &arg2) const
+{
+ if(mpz_cmp_si(arg2._mpz, 0) == 0) return new _knumerror(UndefinedNumber);
+
+ _knuminteger * tmp_num = new _knuminteger();
+
+ mpz_mod(tmp_num->_mpz, _mpz, arg2._mpz);
+
+ return tmp_num;
+}
+
+_knumber * _knuminteger::shift(_knuminteger const &arg2) const
+{
+ mpz_t tmp_mpz;
+
+ mpz_init_set (tmp_mpz, arg2._mpz);
+
+ if (! mpz_fits_slong_p(tmp_mpz)) {
+ mpz_clear(tmp_mpz);
+ return new _knumerror(UndefinedNumber);
+ }
+
+ signed long int tmp_arg2 = mpz_get_si(tmp_mpz);
+ mpz_clear(tmp_mpz);
+
+
+ _knuminteger * tmp_num = new _knuminteger();
+
+ if (tmp_arg2 > 0) // left shift
+ mpz_mul_2exp(tmp_num->_mpz, _mpz, tmp_arg2);
+ else // right shift
+ mpz_tdiv_q_2exp(tmp_num->_mpz, _mpz, -tmp_arg2);
+
+
+ return tmp_num;
+}
+
diff --git a/kcalc/knumber/knumber_priv.h b/kcalc/knumber/knumber_priv.h
new file mode 100644
index 0000000..7dd58a6
--- /dev/null
+++ b/kcalc/knumber/knumber_priv.h
@@ -0,0 +1,313 @@
+/* This file is part of the KDE libraries
+ Copyright (C) 2005 Klaus Niederkrueger <kniederk@math.uni-koeln.de>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+#ifndef _KNUMBER_PRIV_H
+#define _KNUMBER_PRIV_H
+
+class QString;
+
+#include <cstdio>
+#include <gmp.h>
+
+// work-around for pre-C99-libs
+#ifndef INFINITY
+#define INFINITY HUGE_VAL
+#endif
+// this is really ugly
+#ifndef NAN
+#define NAN (atof("nan"))
+#endif
+
+class _knumber
+{
+ public:
+ enum NumType {SpecialType, IntegerType, FractionType, FloatType};
+ enum ErrorType {UndefinedNumber, Infinity, MinusInfinity};
+
+ _knumber() {}
+
+ virtual ~_knumber() {}
+
+ virtual void copy(_knumber const & num) = 0;
+
+ virtual NumType type(void) const = 0;
+
+ virtual QString const ascii(int prec = -1) const = 0;
+
+ virtual _knumber * abs(void) const = 0;
+ virtual _knumber * intPart(void) const = 0;
+ virtual int sign(void) const = 0;
+ virtual _knumber * sqrt(void) const = 0;
+ virtual _knumber * cbrt(void) const = 0;
+ virtual _knumber * change_sign(void) const = 0;
+ virtual _knumber * reciprocal(void) const = 0;
+ virtual _knumber * add(_knumber const & arg2) const = 0;
+ virtual _knumber * multiply(_knumber const & arg2) const = 0;
+ _knumber * divide(_knumber const & arg2) const;
+
+ virtual _knumber * power(_knumber const & exponent) const = 0;
+
+ virtual int compare(_knumber const &arg2) const = 0;
+
+ virtual operator signed long int (void) const = 0;
+ virtual operator unsigned long int (void) const = 0;
+ virtual operator double (void) const = 0;
+};
+
+
+
+class _knumerror : public _knumber
+{
+ public:
+ _knumerror(ErrorType error = UndefinedNumber)
+ : _error(error) { }
+
+ _knumerror(_knumber const & num);
+
+ _knumerror(const QString & num);
+
+ //virtual ~_knumerror() { }
+
+ _knumerror const & operator = (_knumerror const & num);
+
+ virtual void copy(_knumber const & num)
+ {
+ _error = dynamic_cast<_knumerror const &>(num)._error;
+ }
+
+ virtual NumType type(void) const {return SpecialType;}
+
+ virtual QString const ascii(int prec = -1) const;
+
+ virtual _knumber * abs(void) const;
+ virtual _knumber * intPart(void) const;
+ virtual int sign(void) const;
+ virtual _knumber * cbrt(void) const;
+ virtual _knumber * sqrt(void) const;
+ virtual _knumber * change_sign(void) const;
+ virtual _knumber * reciprocal(void) const;
+ virtual _knumber * add(_knumber const & arg2) const;
+ virtual _knumber * multiply(_knumber const & arg2) const;
+
+ virtual _knumber * power(_knumber const & exponent) const;
+
+ virtual int compare(_knumber const &arg2) const;
+
+ virtual operator signed long int (void) const;
+ virtual operator unsigned long int (void) const;
+ virtual operator double (void) const;
+
+ private:
+
+ ErrorType _error;
+
+ friend class _knuminteger;
+ friend class _knumfraction;
+ friend class _knumfloat;
+};
+
+
+
+class _knuminteger : public _knumber
+{
+ public:
+ _knuminteger(signed int num = 0)
+ {
+ mpz_init_set_si(_mpz, num);
+ }
+
+ _knuminteger(unsigned int num)
+ {
+ mpz_init_set_ui(_mpz, num);
+ }
+
+ _knuminteger(signed long int num)
+ {
+ mpz_init_set_si(_mpz, num);
+ }
+
+ _knuminteger(unsigned long int num)
+ {
+ mpz_init_set_ui(_mpz, num);
+ }
+
+ _knuminteger(unsigned long long int num);
+
+ _knuminteger(_knumber const & num);
+
+ _knuminteger(const QString & num);
+
+ virtual ~_knuminteger()
+ {
+ mpz_clear(_mpz);
+ }
+
+ _knuminteger const & operator = (_knuminteger const & num);
+
+ virtual void copy(_knumber const & num)
+ {
+ mpz_set(_mpz, dynamic_cast<_knuminteger const &>(num)._mpz);
+ }
+
+ virtual NumType type(void) const {return IntegerType;}
+
+ virtual QString const ascii(int prec = -1) const;
+
+ virtual _knumber * abs(void) const;
+ virtual _knumber * intPart(void) const;
+ virtual int sign(void) const;
+ virtual _knumber * cbrt(void) const;
+ virtual _knumber * sqrt(void) const;
+ virtual _knumber * change_sign(void) const;
+ virtual _knumber * reciprocal(void) const;
+ virtual _knumber * add(_knumber const & arg2) const;
+ virtual _knumber * multiply(_knumber const & arg2) const;
+
+ virtual int compare(_knumber const &arg2) const;
+
+ virtual _knumber * power(_knumber const & exponent) const;
+
+ virtual operator signed long int (void) const;
+ virtual operator unsigned long int (void) const;
+ virtual operator double (void) const;
+
+ _knuminteger * intAnd(_knuminteger const &arg2) const;
+ _knuminteger * intOr(_knuminteger const &arg2) const;
+ _knumber * mod(_knuminteger const &arg2) const;
+ _knumber * shift(_knuminteger const &arg2) const;
+
+ private:
+ mpz_t _mpz;
+
+ friend class _knumfraction;
+ friend class _knumfloat;
+};
+
+
+
+class _knumfraction : public _knumber
+{
+ public:
+
+ _knumfraction(signed long int nom = 0, signed long int denom = 1)
+ {
+ mpq_init(_mpq);
+ mpq_set_si(_mpq, nom, denom);
+ mpq_canonicalize(_mpq);
+ }
+
+ _knumfraction(_knumber const & num);
+
+ _knumfraction(QString const & num);
+
+ virtual ~_knumfraction()
+ {
+ mpq_clear(_mpq);
+ }
+
+ virtual void copy(_knumber const & num)
+ {
+ mpq_set(_mpq, dynamic_cast<_knumfraction const &>(num)._mpq);
+ }
+
+ virtual NumType type(void) const {return FractionType;}
+
+ virtual QString const ascii(int prec = -1) const;
+
+ bool isInteger(void) const;
+
+ virtual _knumber * abs(void) const;
+ virtual _knumber * intPart(void) const;
+ virtual int sign(void) const;
+ virtual _knumber * cbrt(void) const;
+ virtual _knumber * sqrt(void) const;
+ virtual _knumber * change_sign(void) const;
+ virtual _knumber * reciprocal(void) const;
+ virtual _knumber * add(_knumber const & arg2) const;
+ virtual _knumber * multiply(_knumber const & arg2) const;
+
+ virtual _knumber * power(_knumber const & exponent) const;
+
+ virtual int compare(_knumber const &arg2) const;
+
+ virtual operator signed long int (void) const;
+ virtual operator unsigned long int (void) const;
+ virtual operator double (void) const;
+
+ private:
+ mpq_t _mpq;
+
+ friend class _knuminteger;
+ friend class _knumfloat;
+};
+
+class _knumfloat : public _knumber
+{
+ public:
+ _knumfloat(double num = 1.0)
+ {
+ mpf_init(_mpf);
+ mpf_set_d(_mpf, num);
+ }
+
+ _knumfloat(_knumber const & num);
+
+ _knumfloat(QString const & num);
+
+ virtual ~_knumfloat()
+ {
+ mpf_clear(_mpf);
+ }
+
+ virtual void copy(_knumber const & num)
+ {
+ mpf_set(_mpf, dynamic_cast<_knumfloat const &>(num)._mpf);
+ }
+
+ virtual NumType type(void) const {return FloatType;}
+
+ virtual QString const ascii(int prec = -1) const;
+
+ virtual _knumber * abs(void) const;
+ virtual _knumber * intPart(void) const;
+ virtual int sign(void) const;
+ virtual _knumber * cbrt(void) const;
+ virtual _knumber * sqrt(void) const;
+ virtual _knumber * change_sign(void) const;
+ virtual _knumber * reciprocal(void) const;
+ virtual _knumber * add(_knumber const & arg2) const;
+ virtual _knumber * multiply(_knumber const & arg2) const;
+ virtual _knumber * divide(_knumber const & arg2) const;
+
+ virtual _knumber * power(_knumber const & exponent) const;
+
+ virtual int compare(_knumber const &arg2) const;
+
+ virtual operator signed long int (void) const;
+ virtual operator unsigned long int (void) const;
+ virtual operator double (void) const;
+
+ private:
+ mpf_t _mpf;
+
+ friend class _knuminteger;
+ friend class _knumfraction;
+};
+
+
+#endif // _KNUMBER_PRIV_H
diff --git a/kcalc/knumber/tests/Makefile.am b/kcalc/knumber/tests/Makefile.am
new file mode 100644
index 0000000..73b0600
--- /dev/null
+++ b/kcalc/knumber/tests/Makefile.am
@@ -0,0 +1,32 @@
+# This file is part of the KDE libraries
+# Copyright (C) 1996-1997 Matthias Kalle Dalheimer (kalle@kde.org)
+# (C) 1997-1998 Stephan Kulow (coolo@kde.org)
+
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+
+# This library 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
+# Library General Public License for more details.
+
+# You should have received a copy of the GNU Library General Public License
+# along with this library; see the file COPYING.LIB. If not, write to
+# the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+# Boston, MA 02110-1301, USA.
+
+INCLUDES = -I$(top_srcdir)/kcalc/knumber $(all_includes)
+
+check_PROGRAMS = knumbertest
+
+TESTS = knumbertest
+
+noinst_HEADERS = knumbertest.h
+
+METASOURCES = AUTO
+
+knumbertest_SOURCES = knumbertest.cpp
+knumbertest_LDADD = ../libknumber.la $(LIB_QT) $(LIBGMP)
+knumbertest_LDFLAGS = $(all_libraries) $(KDE_RPATH)
diff --git a/kcalc/knumber/tests/knumbertest.cpp b/kcalc/knumber/tests/knumbertest.cpp
new file mode 100644
index 0000000..814410e
--- /dev/null
+++ b/kcalc/knumber/tests/knumbertest.cpp
@@ -0,0 +1,582 @@
+//
+// Author: Klaus Niederkrueger <kniederk@math.uni-koeln.de>
+//
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <iostream>
+#include <qstring.h>
+
+#include "knumbertest.h"
+
+QString const numtypeToString(KNumber::NumType arg)
+{
+ switch(arg) {
+ case KNumber::SpecialType:
+ return QString("Special");
+ case KNumber::IntegerType:
+ return QString("Integer");
+ case KNumber::FractionType:
+ return QString("Fraction");
+ case KNumber::FloatType:
+ return QString("Float");
+ default:
+ return QString("Unknown:") + QString::number(static_cast<int>(arg));
+
+ }
+}
+
+void checkResult(QString const &string, KNumber const & result,
+ QString const & desired_string, KNumber::NumType desired)
+{
+ std::cout << "Testing result of: " << string.ascii() <<
+ " should give " << desired_string.ascii() << " and gives " <<
+ result.toQString(8).ascii() << "....\n";
+ std::cout << "The type of the result should be " <<
+ numtypeToString(desired).ascii() << " and gives " <<
+ numtypeToString(result.type()).ascii() << ".... ";
+
+ if (result.type() == desired &&
+ result.toQString(8) == desired_string) {
+ std::cout << "OK\n";
+ return;
+ }
+
+ std::cout << "Failed\n";
+ exit(1);
+}
+
+void checkTruth(QString const &string, bool computation,
+ bool desired_result)
+{
+ std::cout << "Testing truth of: " << string.ascii() <<
+ " should be " << desired_result << " and is " <<
+ computation << "....\n";
+
+ if (computation == desired_result) {
+ std::cout << "OK\n";
+ return;
+ }
+
+ std::cout << "Failed\n";
+ exit(1);
+}
+
+
+void checkType(QString const &string, KNumber::NumType test_arg,
+ KNumber::NumType desired)
+{
+ std::cout << "Testing type of: " << string.ascii() << " should give " <<
+ numtypeToString(desired).ascii() << " and gives " <<
+ numtypeToString(test_arg).ascii() << "....";
+
+ if (test_arg == desired) {
+ std::cout << "OK\n";
+ return;
+ }
+
+ std::cout << "Failed\n";
+ exit(1);
+
+}
+
+
+void testingCompare(void)
+{
+ std::cout << "\n\nTesting Compare:\n";
+
+ checkTruth("KNumber(5) == KNumber(2)", KNumber(5) == KNumber(2), false);
+ checkTruth("KNumber(5) > KNumber(2)", KNumber(5) > KNumber(2), true);
+ checkTruth("KNumber(5) < KNumber(2)", KNumber(5) < KNumber(2), false);
+ checkTruth("KNumber(5) < KNumber(0)", KNumber(5) < KNumber(0), false);
+ checkTruth("KNumber(-5) < KNumber(0)", KNumber(-5) < KNumber(0), true);
+ checkTruth("KNumber(5) >= KNumber(2)", KNumber(5) >= KNumber(2), true);
+ checkTruth("KNumber(5) <= KNumber(2)", KNumber(5) <= KNumber(2), false);
+ checkTruth("KNumber(5) != KNumber(2)", KNumber(5) != KNumber(2), true);
+
+ checkTruth("KNumber(2) == KNumber(2)", KNumber(2) == KNumber(2), true);
+ checkTruth("KNumber(2) > KNumber(2)", KNumber(2) > KNumber(2), false);
+ checkTruth("KNumber(2) < KNumber(2)", KNumber(2) < KNumber(2), false);
+ checkTruth("KNumber(2) >= KNumber(2)", KNumber(2) >= KNumber(2), true);
+ checkTruth("KNumber(2) <= KNumber(2)", KNumber(2) <= KNumber(2), true);
+ checkTruth("KNumber(2) != KNumber(2)", KNumber(2) != KNumber(2), false);
+
+ checkTruth("KNumber(5) == KNumber(\"1/2\")", KNumber(5) == KNumber("1/2"), false);
+ checkTruth("KNumber(5) > KNumber(\"1/2\")", KNumber(5) > KNumber("1/2"), true);
+ checkTruth("KNumber(5) < KNumber(\"1/2\")", KNumber(5) < KNumber("1/2"), false);
+ checkTruth("KNumber(5) >= KNumber(\"1/2\")", KNumber(5) >= KNumber("1/2"), true);
+ checkTruth("KNumber(5) <= KNumber(\"1/2\")", KNumber(5) <= KNumber("1/2"), false);
+ checkTruth("KNumber(5) != KNumber(\"1/2\")", KNumber(5) != KNumber("1/2"), true);
+
+ checkTruth("KNumber(\"1/2\") == KNumber(\"1/2\")", KNumber("1/2") == KNumber("1/2"), true);
+ checkTruth("KNumber(\"1/2\") > KNumber(\"1/2\")", KNumber("1/2") > KNumber("1/2"), false);
+ checkTruth("KNumber(\"1/2\") < KNumber(\"1/2\")", KNumber("1/2") < KNumber("1/2"), false);
+ checkTruth("KNumber(\"1/2\") >= KNumber(\"1/2\")", KNumber("1/2") >= KNumber("1/2"), true);
+ checkTruth("KNumber(\"1/2\") <= KNumber(\"1/2\")", KNumber("1/2") <= KNumber("1/2"), true);
+ checkTruth("KNumber(\"1/2\") != KNumber(\"1/2\")", KNumber("1/2") != KNumber("1/2"), false);
+
+ checkTruth("KNumber(\"3/2\") == KNumber(\"1/2\")", KNumber("3/2") == KNumber("1/2"), false);
+ checkTruth("KNumber(\"3/2\") > KNumber(\"1/2\")", KNumber("3/2") > KNumber("1/2"), true);
+ checkTruth("KNumber(\"3/2\") < KNumber(\"1/2\")", KNumber("3/2") < KNumber("1/2"), false);
+ checkTruth("KNumber(\"3/2\") >= KNumber(\"1/2\")", KNumber("3/2") >= KNumber("1/2"), true);
+ checkTruth("KNumber(\"3/2\") <= KNumber(\"1/2\")", KNumber("3/2") <= KNumber("1/2"), false);
+ checkTruth("KNumber(\"3/2\") != KNumber(\"1/2\")", KNumber("3/2") != KNumber("1/2"), true);
+
+}
+
+
+void testingAdditions(void)
+{
+ std::cout << "\n\nTesting additions:\n";
+
+ checkResult("KNumber(5) + KNumber(2)", KNumber(5) + KNumber(2), "7", KNumber::IntegerType);
+ checkResult("KNumber(5) + KNumber(\"2/3\")", KNumber(5) + KNumber("2/3"), "17/3", KNumber::FractionType);
+ checkResult("KNumber(5) + KNumber(\"2.3\")", KNumber(5) + KNumber("2.3"), "7.3", KNumber::FloatType);
+
+ checkResult("KNumber(\"5/3\") + KNumber(2)", KNumber("5/3") + KNumber(2), "11/3", KNumber::FractionType);
+ checkResult("KNumber(\"5/3\") + KNumber(\"2/3\")", KNumber("5/3") + KNumber("2/3"), "7/3", KNumber::FractionType);
+ checkResult("KNumber(\"5/3\") + KNumber(\"1/3\")", KNumber("5/3") + KNumber("1/3"), "2", KNumber::IntegerType);
+ checkResult("KNumber(\"5/3\") + KNumber(\"-26/3\")", KNumber("5/3") + KNumber("-26/3"), "-7", KNumber::IntegerType);
+ checkResult("KNumber(\"5/2\") + KNumber(2.3)", KNumber("5/2") + KNumber(2.3), "4.8", KNumber::FloatType);
+
+ checkResult("KNumber(5.3) + KNumber(2)", KNumber(5.3) + KNumber(2), "7.3", KNumber::FloatType);
+ checkResult("KNumber(5.3) + KNumber(\"2/4\")", KNumber(5.3) + KNumber("2/4"), "5.8", KNumber::FloatType);
+ checkResult("KNumber(5.3) + KNumber(2.3)", KNumber(5.3) + KNumber(2.3), "7.6", KNumber::FloatType);
+
+}
+
+void testingSubtractions(void)
+{
+ std::cout << "\n\nTesting subtractions:\n";
+
+ checkResult("KNumber(5) - KNumber(2)", KNumber(5) - KNumber(2), "3", KNumber::IntegerType);
+ checkResult("KNumber(5) - KNumber(\"2/3\")", KNumber(5) - KNumber("2/3"), "13/3", KNumber::FractionType);
+ checkResult("KNumber(5) - KNumber(2.3)", KNumber(5) - KNumber(2.3), "2.7", KNumber::FloatType);
+
+ checkResult("KNumber(\"5/3\") - KNumber(2)", KNumber("5/3") - KNumber(2), "-1/3", KNumber::FractionType);
+ checkResult("KNumber(\"5/3\") - KNumber(\"1/3\")", KNumber("5/3") - KNumber("1/3"), "4/3", KNumber::FractionType);
+ checkResult("KNumber(\"5/3\") - KNumber(\"2/3\")", KNumber("5/3") - KNumber("2/3"), "1", KNumber::IntegerType);
+ checkResult("KNumber(\"-5/3\") - KNumber(\"4/3\")", KNumber("-5/3") - KNumber("4/3"), "-3", KNumber::IntegerType);
+ checkResult("KNumber(\"5/4\") - KNumber(2.2)", KNumber("5/4") - KNumber(2.2), "-0.95", KNumber::FloatType);
+
+ checkResult("KNumber(5.3) - KNumber(2)", KNumber(5.3) - KNumber(2), "3.3", KNumber::FloatType);
+ checkResult("KNumber(5.3) - KNumber(\"3/4\")", KNumber(5.3) - KNumber("3/4"), "4.55", KNumber::FloatType);
+ checkResult("KNumber(5.3) - KNumber(2.3)", KNumber(5.3) - KNumber(2.3), "3", KNumber::FloatType);
+
+}
+
+
+void testingMultiplications(void)
+{
+ std::cout << "\n\nTesting multiplications:\n";
+
+ checkResult("KNumber(5) * KNumber(2)", KNumber(5) * KNumber(2), "10", KNumber::IntegerType);
+ checkResult("KNumber(5) * KNumber(\"2/3\")", KNumber(5) * KNumber("2/3"), "10/3", KNumber::FractionType);
+ checkResult("KNumber(5) * KNumber(\"2/5\")", KNumber(5) * KNumber("2/5"), "2", KNumber::IntegerType);
+ checkResult("KNumber(5) * KNumber(2.3)", KNumber(5) * KNumber(2.3), "11.5", KNumber::FloatType);
+ checkResult("KNumber(0) * KNumber(\"2/5\")", KNumber(0) * KNumber("2/5"), "0", KNumber::IntegerType);
+ checkResult("KNumber(0) * KNumber(2.3)", KNumber(0) * KNumber(2.3), "0", KNumber::IntegerType);
+
+ checkResult("KNumber(\"5/3\") * KNumber(2)", KNumber("5/3") * KNumber(2), "10/3", KNumber::FractionType);
+ checkResult("KNumber(\"5/3\") * KNumber(0)", KNumber("5/3") * KNumber(0), "0", KNumber::IntegerType);
+ checkResult("KNumber(\"5/3\") * KNumber(\"2/3\")", KNumber("5/3") * KNumber("2/3"), "10/9", KNumber::FractionType);
+ checkResult("KNumber(\"25/6\") * KNumber(\"12/5\")", KNumber("25/6") * KNumber("12/5"), "10", KNumber::IntegerType);
+ checkResult("KNumber(\"5/2\") * KNumber(2.3)", KNumber("5/2") * KNumber(2.3), "5.75",KNumber::FloatType);
+
+ checkResult("KNumber(5.3) * KNumber(2)", KNumber(5.3) * KNumber(2), "10.6", KNumber::FloatType);
+ checkResult("KNumber(5.3) * KNumber(0)", KNumber(5.3) * KNumber(0), "0", KNumber::IntegerType);
+ checkResult("KNumber(5.3) * KNumber(\"1/2\")", KNumber(5.3) * KNumber("1/2"), "2.65", KNumber::FloatType);
+ checkResult("KNumber(5.3) * KNumber(2.3)", KNumber(5.3) * KNumber(2.3), "12.19", KNumber::FloatType);
+
+}
+
+void testingDivisions(void)
+{
+ std::cout << "\n\nTesting divisions:\n";
+
+ checkResult("KNumber(5) / KNumber(2)", KNumber(5) / KNumber(2), "5/2", KNumber::FractionType);
+ checkResult("KNumber(122) / KNumber(2)", KNumber(122) / KNumber(2), "61", KNumber::IntegerType);
+ checkResult("KNumber(12) / KNumber(0)", KNumber(12) / KNumber(0), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-12) / KNumber(0)", KNumber(-12) / KNumber(0), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(5) / KNumber(\"2/3\")", KNumber(5) / KNumber("2/3"), "15/2", KNumber::FractionType);
+ checkResult("KNumber(6) / KNumber(\"2/3\")", KNumber(6) / KNumber("2/3"), "9", KNumber::IntegerType);
+ checkResult("KNumber(5) / KNumber(2.5)", KNumber(5) / KNumber(2.5), "2", KNumber::FloatType);
+ checkResult("KNumber(5) / KNumber(0.0)", KNumber(5) / KNumber(0.0), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5) / KNumber(0.0)", KNumber(-5) / KNumber(0.0), "-inf", KNumber::SpecialType);
+
+ checkResult("KNumber(\"5/3\") / KNumber(2)", KNumber("5/3") / KNumber(2), "5/6", KNumber::FractionType);
+ checkResult("KNumber(\"5/3\") / KNumber(0)", KNumber("5/3") / KNumber(0), "inf", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") / KNumber(0)", KNumber("-5/3") / KNumber(0), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(\"5/3\") / KNumber(\"2/3\")", KNumber("5/3") / KNumber("2/3"), "5/2", KNumber::FractionType);
+ checkResult("KNumber(\"49/3\") / KNumber(\"7/9\")", KNumber("49/3") / KNumber("7/9"), "21", KNumber::IntegerType);
+ checkResult("KNumber(\"5/2\") / KNumber(2.5)", KNumber("5/2") / KNumber(2.5), "1", KNumber::FloatType);
+ checkResult("KNumber(\"5/2\") / KNumber(0.0)", KNumber("5/2") / KNumber(0.0), "inf", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/2\") / KNumber(0.0)", KNumber("-5/2") / KNumber(0.0), "-inf", KNumber::SpecialType);
+
+ checkResult("KNumber(5.3) / KNumber(2)", KNumber(5.3) / KNumber(2), "2.65", KNumber::FloatType);
+ checkResult("KNumber(5.3) / KNumber(0)", KNumber(5.3) / KNumber(0), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5.3) / KNumber(0)", KNumber(-5.3) / KNumber(0), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(5.3) / KNumber(\"2/3\")", KNumber(5.3) / KNumber("2/3"), "7.95", KNumber::FloatType);
+ checkResult("KNumber(5.5) / KNumber(2.5)", KNumber(5.5) / KNumber(2.5), "2.2", KNumber::FloatType);
+ checkResult("KNumber(5.5) / KNumber(0.0)", KNumber(5.5) / KNumber(0.0), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5.5) / KNumber(0.0)", KNumber(-5.5) / KNumber(0.0), "-inf", KNumber::SpecialType);
+}
+
+void testingModulus(void)
+{
+ std::cout << "\n\nTesting modulus:\n";
+
+ checkResult("KNumber(23) % KNumber(4)", KNumber(23) % KNumber(4), "3", KNumber::IntegerType);
+ checkResult("KNumber(12) % KNumber(-5)", KNumber(12) % KNumber(-5), "2", KNumber::IntegerType);
+ checkResult("KNumber(-12) % KNumber(5)", KNumber(-12) % KNumber(5), "3", KNumber::IntegerType);
+ checkResult("KNumber(12) % KNumber(0)", KNumber(-12) % KNumber(0), "nan", KNumber::SpecialType);
+ checkResult("KNumber(-12) % KNumber(0)", KNumber(-12) % KNumber(0), "nan", KNumber::SpecialType);
+
+#warning test for other types
+
+}
+
+void testingAndOr(void)
+{
+ std::cout << "\n\nTesting And/Or:\n";
+
+ checkResult("KNumber(17) & KNumber(9)", KNumber(17) & KNumber(9), "1", KNumber::IntegerType);
+ checkResult("KNumber(17) | KNumber(9)", KNumber(17) | KNumber(9), "25", KNumber::IntegerType);
+ checkResult("KNumber(1023) & KNumber(255)", KNumber(1023) & KNumber(255), "255", KNumber::IntegerType);
+ checkResult("KNumber(1023) | KNumber(255)", KNumber(1023) | KNumber(255), "1023", KNumber::IntegerType);
+
+#warning test for other types
+
+}
+
+
+void testingAbs(void)
+{
+ std::cout << "\n\nTesting absolute value:\n";
+
+ checkResult("KNumber(5).abs()", KNumber(5).abs(), "5", KNumber::IntegerType);
+ checkResult("KNumber(\"2/3\").abs()", KNumber("2/3").abs(), "2/3", KNumber::FractionType);
+ checkResult("KNumber(\"2.3\").abs()", KNumber("2.3").abs(), "2.3", KNumber::FloatType);
+
+ checkResult("KNumber(-5).abs()", KNumber(-5).abs(), "5", KNumber::IntegerType);
+ checkResult("KNumber(\"-2/3\").abs()", KNumber("-2/3").abs(), "2/3", KNumber::FractionType);
+ checkResult("KNumber(\"-2.3\").abs()", KNumber("-2.3").abs(), "2.3", KNumber::FloatType);
+}
+
+void testingTruncateToInteger(void)
+{
+ std::cout << "\n\nTesting truncate to an integer:\n";
+
+ checkResult("KNumber(16).integerPart()", KNumber(16).integerPart(), "16", KNumber::IntegerType);
+ checkResult("KNumber(\"43/9\").integerPart()", KNumber("43/9").integerPart(), "4", KNumber::IntegerType);
+ checkResult("KNumber(\"-43/9\").integerPart()", KNumber("-43/9").integerPart(), "-4", KNumber::IntegerType);
+ checkResult("KNumber(\"5.25\").integerPart()", KNumber("5.25").integerPart(), "5", KNumber::IntegerType);
+ checkResult("KNumber(\"-5.25\").integerPart()", KNumber("-5.25").integerPart(), "-5", KNumber::IntegerType);
+}
+
+
+void testingSqrt(void)
+{
+ std::cout << "\n\nTesting square root, cubic root:\n";
+
+ checkResult("KNumber(16).sqrt()", KNumber(16).sqrt(), "4", KNumber::IntegerType);
+ checkResult("KNumber(-16).sqrt()", KNumber(-16).sqrt(), "nan", KNumber::SpecialType);
+ checkResult("KNumber(\"16/9\").sqrt()", KNumber("16/9").sqrt(), "4/3", KNumber::FractionType);
+ checkResult("KNumber(\"-16/9\").sqrt()", KNumber("-16/9").sqrt(), "nan", KNumber::SpecialType);
+ checkResult("KNumber(2).sqrt()", KNumber(2).sqrt(), "1.4142136", KNumber::FloatType);
+ checkResult("KNumber(\"2/3\").sqrt()", KNumber("2/3").sqrt(), "0.81649658", KNumber::FloatType);
+ checkResult("KNumber(\"0.25\").sqrt()", KNumber("0.25").sqrt(), "0.5", KNumber::FloatType);
+ checkResult("KNumber(\"-0.25\").sqrt()", KNumber("-0.25").sqrt(), "nan", KNumber::SpecialType);
+
+
+ checkResult("KNumber(27).cbrt()", KNumber(27).cbrt(), "3", KNumber::IntegerType);
+ checkResult("KNumber(-27).cbrt()", KNumber(-27).cbrt(), "-3", KNumber::IntegerType);
+ checkResult("KNumber(\"27/8\").cbrt()", KNumber("27/8").cbrt(), "3/2", KNumber::FractionType);
+ checkResult("KNumber(\"-8/27\").cbrt()", KNumber("-8/27").cbrt(), "-2/3", KNumber::FractionType);
+#warning need to check non-perfect cube roots
+ // checkResult("KNumber(2).cbrt()", KNumber(2).cbrt(), "1.4142136", KNumber::FloatType);
+ // checkResult("KNumber(\"2/3\").cbrt()", KNumber("2/3").cbrt(), "0.81649658", KNumber::FloatType);
+ // checkResult("KNumber(\"0.25\").cbrt()", KNumber("0.25").cbrt(), "0.5", KNumber::FloatType);
+ // checkResult("KNumber(\"-0.25\").cbrt()", KNumber("-0.25").cbrt(), "nan", KNumber::SpecialType);
+
+}
+
+void testingShifts(void)
+{
+ std::cout << "\n\nTesting left/right shift:\n";
+
+ checkResult("KNumber(16) << KNumber(2)", KNumber(16) << KNumber(2), "64", KNumber::IntegerType);
+ checkResult("KNumber(16) >> KNumber(2)", KNumber(16) >> KNumber(2), "4", KNumber::IntegerType);
+
+}
+
+void testingPower(void)
+{
+ std::cout << "\n\nTesting Power:\n";
+
+ checkResult("KNumber(0) ^ KNumber(-4)", KNumber(0).power(KNumber(-4)), "inf", KNumber::SpecialType);
+ checkResult("KNumber(5) ^ KNumber(4)", KNumber(5).power(KNumber(4)), "625", KNumber::IntegerType);
+ checkResult("KNumber(122) ^ KNumber(0)", KNumber(122).power(KNumber(0)), "1", KNumber::IntegerType);
+ checkResult("KNumber(-5) ^ KNumber(0)", KNumber(-5).power(KNumber(0)), "nan", KNumber::SpecialType);
+ checkResult("KNumber(-2) ^ KNumber(3)", KNumber(-2).power(KNumber(3)), "-8", KNumber::IntegerType);
+ checkResult("KNumber(-2) ^ KNumber(4)", KNumber(-2).power(KNumber(4)), "16", KNumber::IntegerType);
+ checkResult("KNumber(5) ^ KNumber(-2)", KNumber(5).power(KNumber(-2)), "1/25", KNumber::FractionType);
+ checkResult("KNumber(8) ^ KNumber(\"2/3\")", KNumber(8).power(KNumber("2/3")), "4", KNumber::IntegerType);
+ checkResult("KNumber(8) ^ KNumber(\"-2/3\")", KNumber(8).power(KNumber("-2/3")), "1/4", KNumber::FractionType);
+ checkResult("KNumber(-16) ^ KNumber(\"1/4\")", KNumber(-16).power(KNumber("1/4")), "nan", KNumber::SpecialType);
+ checkResult("KNumber(-8) ^ KNumber(\"1/3\")", KNumber(-8).power(KNumber("1/3")), "nan", KNumber::SpecialType);
+ checkResult("KNumber(5) ^ KNumber(0.0)", KNumber(5).power(KNumber(0.0)), "1", KNumber::IntegerType);
+ checkResult("KNumber(-5) ^ KNumber(0.0)", KNumber(-5).power(KNumber(0.0)), "nan", KNumber::SpecialType);
+
+ checkResult("KNumber(\"5/3\") ^ KNumber(2)", KNumber("5/3").power(KNumber(2)), "25/9", KNumber::FractionType);
+ checkResult("KNumber(\"5/3\") ^ KNumber(0)", KNumber("5/3").power(KNumber(0)), "1", KNumber::IntegerType);
+ checkResult("KNumber(\"-5/3\") ^ KNumber(0)", KNumber("-5/3").power(KNumber(0)), "nan", KNumber::SpecialType);
+ checkResult("KNumber(\"8/27\") ^ KNumber(\"2/3\")", KNumber("8/27").power(KNumber("2/3")), "4/9", KNumber::FractionType);
+ checkResult("KNumber(\"49/3\") ^ KNumber(\"7/9\")", KNumber("49/3").power(KNumber("7/9")), "21", KNumber::IntegerType);
+ checkResult("KNumber(\"5/2\") ^ KNumber(2.5)", KNumber("5/2").power(KNumber(2.5)), "1", KNumber::FloatType);
+ checkResult("KNumber(\"5/2\") ^ KNumber(0.0)", KNumber("5/2").power(KNumber(0.0)), "inf", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/2\") ^ KNumber(0.0)", KNumber("-5/2").power(KNumber(0.0)), "-inf", KNumber::SpecialType);
+
+ checkResult("KNumber(5.3) ^ KNumber(2)", KNumber(5.3).power(KNumber(2)), "2.65", KNumber::FloatType);
+ checkResult("KNumber(5.3) ^ KNumber(0)", KNumber(5.3).power(KNumber(0)), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5.3) ^ KNumber(0)", KNumber(-5.3).power(KNumber(0)), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(5.3) ^ KNumber(\"2/3\")", KNumber(5.3).power(KNumber("2/3")), "7.95", KNumber::FloatType);
+ checkResult("KNumber(5.5) ^ KNumber(2.5)", KNumber(5.5).power(KNumber(2.5)), "2.2", KNumber::FloatType);
+ checkResult("KNumber(5.5) ^ KNumber(0.0)", KNumber(5.5).power(KNumber(0.0)), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5.5) ^ KNumber(0.0)", KNumber(-5.5).power(KNumber(0.0)), "-inf", KNumber::SpecialType);
+}
+
+void testingInfArithmetic(void)
+{
+ std::cout << "\n\nTesting inf/nan-arithmetics:\n";
+
+ KNumber tmp_inf = KNumber("inf");
+ KNumber tmp_mininf = KNumber("-inf");
+ KNumber tmp_nan = KNumber("nan");
+
+ checkResult("inf + KNumber(2)", tmp_inf + KNumber(2), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5) + inf", KNumber(-5) + tmp_inf, "inf", KNumber::SpecialType);
+ checkResult("inf + KNumber(\"1/2\")", tmp_inf + KNumber("1/2"), "inf", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") + inf", KNumber("-5/3") + tmp_inf, "inf", KNumber::SpecialType);
+ checkResult("inf + KNumber(2.01)", tmp_inf + KNumber(2.01), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5.4) + inf", KNumber(-5.4) + tmp_inf, "inf", KNumber::SpecialType);
+ checkResult("mininf + KNumber(2)", tmp_mininf + KNumber(2), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(-5) + mininf", KNumber(-5) + tmp_mininf, "-inf", KNumber::SpecialType);
+ checkResult("mininf + KNumber(\"1/2\")", tmp_mininf + KNumber("1/2"), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") + mininf", KNumber("-5/3") + tmp_mininf, "-inf", KNumber::SpecialType);
+ checkResult("mininf + KNumber(2.01)", tmp_mininf + KNumber(2.01), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(-5.4) + mininf", KNumber(-5.4) + tmp_mininf, "-inf", KNumber::SpecialType);
+ checkResult("nan + KNumber(2)", tmp_nan + KNumber(2), "nan", KNumber::SpecialType);
+ checkResult("KNumber(-5) + nan", KNumber(-5) + tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("nan + KNumber(\"1/2\")", tmp_nan + KNumber("1/2"), "nan", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") + nan", KNumber("-5/3") + tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("nan + KNumber(2.01)", tmp_nan + KNumber(2.01), "nan", KNumber::SpecialType);
+ checkResult("KNumber(-5.4) + nan", KNumber(-5.4) + tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("inf + inf", tmp_inf + tmp_inf, "inf", KNumber::SpecialType);
+ checkResult("inf + mininf", tmp_inf + tmp_mininf, "nan", KNumber::SpecialType);
+ checkResult("mininf + inf", tmp_mininf + tmp_inf, "nan", KNumber::SpecialType);
+ checkResult("mininf + mininf", tmp_mininf + tmp_mininf, "-inf", KNumber::SpecialType);
+ checkResult("inf + nan", tmp_inf + tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("mininf + nan", tmp_mininf + tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("nan + inf", tmp_nan + tmp_inf, "nan", KNumber::SpecialType);
+ checkResult("mininf + nan", tmp_mininf + tmp_nan, "nan", KNumber::SpecialType);
+
+
+ checkResult("inf - KNumber(2)", tmp_inf - KNumber(2), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5) - inf", KNumber(-5) - tmp_inf, "-inf", KNumber::SpecialType);
+ checkResult("inf - KNumber(\"1/2\")", tmp_inf - KNumber("1/2"), "inf", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") - inf", KNumber("-5/3") - tmp_inf, "-inf", KNumber::SpecialType);
+ checkResult("inf - KNumber(2.01)", tmp_inf - KNumber(2.01), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5.4) - inf", KNumber(-5.4) - tmp_inf, "-inf", KNumber::SpecialType);
+ checkResult("mininf - KNumber(2)", tmp_mininf - KNumber(2), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(-5) - mininf", KNumber(-5) - tmp_mininf, "inf", KNumber::SpecialType);
+ checkResult("mininf - KNumber(\"1/2\")", tmp_mininf - KNumber("1/2"), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") - mininf", KNumber("-5/3") - tmp_mininf, "inf", KNumber::SpecialType);
+ checkResult("mininf - KNumber(2.01)", tmp_mininf - KNumber(2.01), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(-5.4) - mininf", KNumber(-5.4) - tmp_mininf, "inf", KNumber::SpecialType);
+ checkResult("nan - KNumber(2)", tmp_nan - KNumber(2), "nan", KNumber::SpecialType);
+ checkResult("KNumber(-5) - nan", KNumber(-5) - tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("nan - KNumber(\"1/2\")", tmp_nan - KNumber("1/2"), "nan", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") - nan", KNumber("-5/3") - tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("nan - KNumber(2.01)", tmp_nan - KNumber(2.01), "nan", KNumber::SpecialType);
+ checkResult("KNumber(-5.4) - nan", KNumber(-5.4) - tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("inf - inf", tmp_inf - tmp_inf, "nan", KNumber::SpecialType);
+ checkResult("inf - mininf", tmp_inf - tmp_mininf, "inf", KNumber::SpecialType);
+ checkResult("mininf - inf", tmp_mininf - tmp_inf, "-inf", KNumber::SpecialType);
+ checkResult("mininf - mininf", tmp_mininf - tmp_mininf, "nan", KNumber::SpecialType);
+ checkResult("inf - nan", tmp_inf - tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("mininf - nan", tmp_mininf - tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("nan - inf", tmp_nan - tmp_inf, "nan", KNumber::SpecialType);
+ checkResult("mininf - nan", tmp_mininf - tmp_nan, "nan", KNumber::SpecialType);
+
+
+ checkResult("inf * KNumber(2)", tmp_inf * KNumber(2), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5) * inf", KNumber(-5) * tmp_inf, "-inf", KNumber::SpecialType);
+ checkResult("inf * KNumber(\"1/2\")", tmp_inf * KNumber("1/2"), "inf", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") * inf", KNumber("-5/3") * tmp_inf, "-inf", KNumber::SpecialType);
+ checkResult("inf * KNumber(2.01)", tmp_inf * KNumber(2.01), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5.4) * inf", KNumber(-5.4) * tmp_inf, "-inf", KNumber::SpecialType);
+ checkResult("mininf * KNumber(2)", tmp_mininf * KNumber(2), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(-5) * mininf", KNumber(-5) * tmp_mininf, "inf", KNumber::SpecialType);
+ checkResult("mininf * KNumber(\"1/2\")", tmp_mininf * KNumber("1/2"), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") * mininf", KNumber("-5/3") * tmp_mininf, "inf", KNumber::SpecialType);
+ checkResult("mininf * KNumber(2.01)", tmp_mininf * KNumber(2.01), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(-5.4) * mininf", KNumber(-5.4) * tmp_mininf, "inf", KNumber::SpecialType);
+ checkResult("nan * KNumber(2)", tmp_nan * KNumber(2), "nan", KNumber::SpecialType);
+ checkResult("KNumber(-5) * nan", KNumber(-5) * tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("nan * KNumber(\"1/2\")", tmp_nan * KNumber("1/2"), "nan", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") * nan", KNumber("-5/3") * tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("nan * KNumber(2.01)", tmp_nan * KNumber(2.01), "nan", KNumber::SpecialType);
+ checkResult("KNumber(-5.4) * nan", KNumber(-5.4) * tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("inf * inf", tmp_inf * tmp_inf, "inf", KNumber::SpecialType);
+ checkResult("inf * mininf", tmp_inf * tmp_mininf, "-inf", KNumber::SpecialType);
+ checkResult("mininf * inf", tmp_mininf * tmp_inf, "-inf", KNumber::SpecialType);
+ checkResult("mininf * mininf", tmp_mininf * tmp_mininf, "inf", KNumber::SpecialType);
+ checkResult("inf * nan", tmp_inf * tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("mininf * nan", tmp_mininf * tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("nan * inf", tmp_nan * tmp_inf, "nan", KNumber::SpecialType);
+ checkResult("mininf * nan", tmp_mininf * tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("KNumber(0) * inf", KNumber(0) * tmp_inf, "nan", KNumber::SpecialType);
+ checkResult("KNumber(0) * mininf", KNumber(0) * tmp_mininf, "nan", KNumber::SpecialType);
+ checkResult("inf * KNumber(0)", tmp_inf * KNumber(0), "nan", KNumber::SpecialType);
+ checkResult("mininf * KNumber(0)", tmp_mininf * KNumber(0), "nan", KNumber::SpecialType);
+ checkResult("KNumber(0.0) * inf", KNumber(0.0) * tmp_inf, "nan", KNumber::SpecialType);
+ checkResult("KNumber(0.0) * mininf", KNumber(0.0) * tmp_mininf, "nan", KNumber::SpecialType);
+ checkResult("inf * KNumber(0.0)", tmp_inf * KNumber(0.0), "nan", KNumber::SpecialType);
+ checkResult("mininf * KNumber(0.0)", tmp_mininf * KNumber(0.0), "nan", KNumber::SpecialType);
+
+
+ checkResult("inf / KNumber(2)", tmp_inf / KNumber(2), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5) / inf", KNumber(-5) / tmp_inf, "0", KNumber::IntegerType);
+ checkResult("inf / KNumber(\"1/2\")", tmp_inf / KNumber("1/2"), "inf", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") / inf", KNumber("-5/3") / tmp_inf, "0", KNumber::IntegerType);
+ checkResult("inf / KNumber(2.01)", tmp_inf / KNumber(2.01), "inf", KNumber::SpecialType);
+ checkResult("KNumber(-5.4) / inf", KNumber(-5.4) / tmp_inf, "0", KNumber::IntegerType);
+ checkResult("mininf / KNumber(2)", tmp_mininf / KNumber(2), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(-5) / mininf", KNumber(-5) / tmp_mininf, "0", KNumber::IntegerType);
+ checkResult("mininf / KNumber(\"1/2\")", tmp_mininf / KNumber("1/2"), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") / mininf", KNumber("-5/3") / tmp_mininf, "0", KNumber::IntegerType);
+ checkResult("mininf / KNumber(2.01)", tmp_mininf / KNumber(2.01), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(-5.4) / mininf", KNumber(-5.4) / tmp_mininf, "0", KNumber::IntegerType);
+ checkResult("nan / KNumber(2)", tmp_nan / KNumber(2), "nan", KNumber::SpecialType);
+ checkResult("KNumber(-5) / nan", KNumber(-5) / tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("nan / KNumber(\"1/2\")", tmp_nan / KNumber("1/2"), "nan", KNumber::SpecialType);
+ checkResult("KNumber(\"-5/3\") / nan", KNumber("-5/3") / tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("nan / KNumber(2.01)", tmp_nan / KNumber(2.01), "nan", KNumber::SpecialType);
+ checkResult("KNumber(-5.4) / nan", KNumber(-5.4) / tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("inf / inf", tmp_inf / tmp_inf, "nan", KNumber::SpecialType);
+ checkResult("inf / mininf", tmp_inf / tmp_mininf, "nan", KNumber::SpecialType);
+ checkResult("mininf / inf", tmp_mininf / tmp_inf, "nan", KNumber::SpecialType);
+ checkResult("mininf / mininf", tmp_mininf / tmp_mininf, "nan", KNumber::SpecialType);
+ checkResult("inf / nan", tmp_inf / tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("mininf / nan", tmp_mininf / tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("nan / inf", tmp_nan / tmp_inf, "nan", KNumber::SpecialType);
+ checkResult("mininf / nan", tmp_mininf / tmp_nan, "nan", KNumber::SpecialType);
+ checkResult("KNumber(0) / inf", KNumber(0) / tmp_inf, "0", KNumber::IntegerType);
+ checkResult("KNumber(0) / mininf", KNumber(0) / tmp_mininf, "0", KNumber::IntegerType);
+ checkResult("inf / KNumber(0)", tmp_inf / KNumber(0), "inf", KNumber::SpecialType);
+ checkResult("mininf / KNumber(0)", tmp_mininf / KNumber(0), "-inf", KNumber::SpecialType);
+ checkResult("KNumber(0.0) / inf", KNumber(0.0) / tmp_inf, "0", KNumber::IntegerType);
+ checkResult("KNumber(0.0) / mininf", KNumber(0.0) / tmp_mininf, "0", KNumber::IntegerType);
+ checkResult("inf / KNumber(0.0)", tmp_inf / KNumber(0.0), "inf", KNumber::SpecialType);
+ checkResult("mininf / KNumber(0.0)", tmp_mininf / KNumber(0.0), "-inf", KNumber::SpecialType);
+}
+
+void testingFloatPrecision(void)
+{
+ KNumber::setDefaultFloatPrecision(100);
+ checkResult("Precision >= 100: (KNumber(1) + KNumber(\"1e-80\")) - KNumber(1)",
+ (KNumber(1) + KNumber("1e-80")) - KNumber(1), "1e-80", KNumber::FloatType);
+ checkResult("Precision >= 100: (KNumber(1) + KNumber(\"1e-980\")) - KNumber(1)",
+ (KNumber(1) + KNumber("1e-980")) - KNumber(1), "0", KNumber::FloatType);
+
+ KNumber::setDefaultFloatPrecision(1000);
+ checkResult("Precision >= 1000: (KNumber(1) + KNumber(\"1e-980\")) - KNumber(1)",
+ (KNumber(1) + KNumber("1e-980")) - KNumber(1), "1e-980", KNumber::FloatType);
+
+}
+
+void testingOutput(void)
+{
+ KNumber::setDefaultFloatOutput(false);
+ checkResult("Fractional output: KNumber(\"1/4\")", KNumber("1/4"), "1/4", KNumber::FractionType);
+ KNumber::setDefaultFloatOutput(true);
+ checkResult("Float: KNumber(\"1/4\")", KNumber("1/4"), "0.25", KNumber::FractionType);
+ KNumber::setDefaultFloatOutput(false);
+ KNumber::setSplitoffIntegerForFractionOutput(true);
+ checkResult("Fractional output: KNumber(\"1/4\")", KNumber("1/4"), "1/4", KNumber::FractionType);
+ checkResult("Fractional output: KNumber(\"-1/4\")", KNumber("-1/4"), "-1/4", KNumber::FractionType);
+ checkResult("Fractional output: KNumber(\"21/4\")", KNumber("21/4"), "5 1/4", KNumber::FractionType);
+ checkResult("Fractional output: KNumber(\"-21/4\")", KNumber("-21/4"), "-5 1/4", KNumber::FractionType);
+ KNumber::setSplitoffIntegerForFractionOutput(false);
+ checkResult("Fractional output: KNumber(\"1/4\")", KNumber("1/4"), "1/4", KNumber::FractionType);
+ checkResult("Fractional output: KNumber(\"-1/4\")", KNumber("-1/4"), "-1/4", KNumber::FractionType);
+ checkResult("Fractional output: KNumber(\"21/4\")", KNumber("21/4"), "21/4", KNumber::FractionType);
+ checkResult("Fractional output: KNumber(\"-21/4\")", KNumber("-21/4"), "-21/4", KNumber::FractionType);
+}
+
+
+int main(void)
+{
+ std::cout << "Testing Constructors:\n";
+
+ checkResult("KNumber(5)", KNumber(5), "5", KNumber::IntegerType);
+ checkType("KNumber(5.3)", KNumber(5.3).type(), KNumber::FloatType);
+ checkType("KNumber(0.0)", KNumber(0.0).type(), KNumber::FloatType);
+
+ checkResult("KNumber(\"5\")", KNumber("5"), "5", KNumber::IntegerType);
+ checkResult("KNumber(\"5/3\")", KNumber("5/3"), "5/3", KNumber::FractionType);
+ checkResult("KNumber(\"5/1\")", KNumber("5/1"), "5", KNumber::IntegerType);
+ checkResult("KNumber(\"0/12\")", KNumber("0/12"), "0", KNumber::IntegerType);
+ KNumber::setDefaultFractionalInput(true);
+ std::cout << "Read decimals as fractions:\n";
+ checkResult("KNumber(\"5\")", KNumber("5"), "5", KNumber::IntegerType);
+ checkResult("KNumber(\"1.2\")", KNumber("1.2"), "6/5", KNumber::FractionType);
+ checkResult("KNumber(\"-0.02\")", KNumber("-0.02"), "-1/50", KNumber::FractionType);
+ checkResult("KNumber(\"5e-2\")", KNumber("5e-2"), "1/20", KNumber::FractionType);
+ checkResult("KNumber(\"1.2e3\")", KNumber("1.2e3"), "1200", KNumber::IntegerType);
+ checkResult("KNumber(\"0.02e+1\")", KNumber("0.02e+1"), "1/5", KNumber::FractionType);
+
+ KNumber::setDefaultFractionalInput(false);
+ std::cout << "Read decimals as floats:\n";
+ checkResult("KNumber(\"5.3\")", KNumber("5.3"), "5.3", KNumber::FloatType);
+
+ checkResult("KNumber(\"nan\")", KNumber("nan"), "nan", KNumber::SpecialType);
+ checkResult("KNumber(\"inf\")", KNumber("inf"), "inf", KNumber::SpecialType);
+ checkResult("KNumber(\"-inf\")", KNumber("-inf"), "-inf", KNumber::SpecialType);
+
+ std::cout << "\n\nConstants:\n";
+
+ checkType("KNumber::Zero", KNumber::Zero.type(), KNumber::IntegerType);
+ checkType("KNumber::One", KNumber::One.type(), KNumber::IntegerType);
+ checkType("KNumber::MinusOne", KNumber::MinusOne.type(), KNumber::IntegerType);
+ checkType("KNumber::Pi", KNumber::Pi.type(), KNumber::FloatType);
+
+ testingCompare();
+
+ testingAdditions();
+ testingSubtractions();
+ testingMultiplications();
+ testingDivisions();
+
+ testingAndOr();
+ testingModulus();
+
+ testingAbs();
+ testingSqrt();
+ //testingPower();
+ testingTruncateToInteger();
+
+ testingShifts();
+
+ testingInfArithmetic();
+
+ testingFloatPrecision();
+
+ testingOutput();
+
+ return 0;
+}
+
+
diff --git a/kcalc/knumber/tests/knumbertest.h b/kcalc/knumber/tests/knumbertest.h
new file mode 100644
index 0000000..b93dc4a
--- /dev/null
+++ b/kcalc/knumber/tests/knumbertest.h
@@ -0,0 +1,9 @@
+#ifndef KNUMBERTEST_H
+#define KNUMBERTEST_H
+
+#include "knumber.h"
+
+/** test: a small test program for KNumber
+ */
+
+#endif // KNUMBERTEST_H
diff --git a/kcalc/stats.cpp b/kcalc/stats.cpp
new file mode 100644
index 0000000..909bed6
--- /dev/null
+++ b/kcalc/stats.cpp
@@ -0,0 +1,196 @@
+/*
+ $Id$
+
+ KCalc, a scientific calculator for the X window system using the
+ Qt widget libraries, available at no cost at http://www.troll.no
+
+ Copyright (C) 1996 Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+
+#include "stats.h"
+#ifdef DEBUG_STATS
+ #include <stdio.h>
+#endif
+
+KStats::KStats() {
+ error_flag = false;
+}
+
+KStats::~KStats() {
+}
+
+void KStats::clearAll() {
+ mData.clear();
+}
+
+void KStats::enterData(KNumber const & _data) {
+
+ mData.push_back(_data);
+#ifdef DEBUG_STATS
+ printf("Added %Lg\n", _data);
+ printf("count %d\n", mData.size());
+#endif
+
+}
+
+
+void KStats::clearLast(void) {
+
+ mData.pop_back();
+#ifdef DEBUG_STATS
+ printf("count %d\n",mData.size());
+#endif
+
+
+}
+
+KNumber KStats::sum(void) {
+
+ KNumber result = 0;
+ QValueVector<KNumber>::iterator p;
+
+ for(p = mData.begin(); p != mData.end(); ++p) {
+ result += *p;
+ }
+
+#ifdef DEBUG_STATS
+ printf("Sum %Lg\n", result);
+#endif
+
+ return result;
+}
+
+KNumber KStats::median(void) {
+
+ KNumber result = 0;
+ unsigned int bound;
+ size_t index;
+
+ bound = count();
+
+ if (bound == 0){
+ error_flag = true;
+ return 0;
+ }
+
+ if (bound == 1)
+ return mData.at(0);
+
+ // need to copy mData-list, because sorting afterwards
+ QValueVector<KNumber> tmp_mData(mData);
+ qHeapSort(tmp_mData);
+
+ if( bound & 1) { // odd
+ index = (bound - 1 ) / 2 + 1;
+ result = tmp_mData.at(index - 1);
+ } else { // even
+ index = bound / 2;
+ result = ((tmp_mData.at(index - 1)) + (tmp_mData.at(index))) / KNumber(2);
+ }
+
+ return result;
+}
+
+
+KNumber KStats::std_kernel(void)
+{
+ KNumber result = KNumber::Zero;
+ KNumber _mean;
+ QValueVector<KNumber>::iterator p;
+
+ _mean = mean();
+
+ for(p = mData.begin(); p != mData.end(); ++p) {
+ result += (*p - _mean) * (*p - _mean);
+ }
+
+ return result;
+}
+
+
+KNumber KStats::sum_of_squares() {
+
+ KNumber result = 0;
+ QValueVector<KNumber>::iterator p;
+
+ for(p = mData.begin(); p != mData.end(); ++p) {
+ result += ((*p) * (*p));
+ }
+
+ return result;
+}
+
+
+KNumber KStats::mean(void)
+{
+ if(count() == 0){
+ error_flag = true;
+ return 0;
+ }
+
+ return (sum() / KNumber(count()));
+}
+
+
+KNumber KStats::std(void)
+{
+ if(count() == 0){
+ error_flag = true;
+ return KNumber::Zero;
+ }
+
+ return (std_kernel() / KNumber(count())).sqrt();
+}
+
+
+KNumber KStats::sample_std(void) {
+ KNumber result = 0;
+
+ if(count() < 2 ){
+ error_flag = true;
+ return KNumber::Zero;
+ }
+
+ result = (std_kernel() / KNumber(count() - 1)).sqrt();
+
+ // result = result/(count() - 1);
+#ifdef DEBUG_STATS
+ printf("sample std: %Lg\n",result);
+#endif
+
+ return result;
+}
+
+
+int KStats::count(void) const
+{
+ return static_cast<int>(mData.size());
+}
+
+
+bool KStats::error() {
+
+ bool value = error_flag;
+ error_flag = false;
+ return value;
+}
+
+
+
diff --git a/kcalc/stats.h b/kcalc/stats.h
new file mode 100644
index 0000000..48b7ddc
--- /dev/null
+++ b/kcalc/stats.h
@@ -0,0 +1,60 @@
+/*
+ $Id$
+
+ KCalc, a scientific calculator for the X window system using the
+ Qt widget libraries, available at no cost at http://www.troll.no
+
+ Copyright (C) 1996 Bernd Johannes Wuebben
+ wuebben@math.cornell.edu
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+*/
+
+#ifndef KSTATS_H
+#define KSTATS_H
+
+#include <qvaluevector.h>
+#include "knumber.h"
+
+class KStats {
+
+public:
+ KStats();
+ ~KStats();
+
+public:
+ void clearAll();
+ void enterData(const KNumber & data);
+ void clearLast();
+ KNumber sum();
+ KNumber sum_of_squares();
+ KNumber mean();
+ KNumber median();
+ KNumber std_kernel();
+ KNumber std();
+ KNumber sample_std();
+ int count() const;
+ bool error();
+
+private:
+ QValueVector<KNumber> mData;
+ bool error_flag;
+
+};
+
+
+#endif /*KSTATS_H*/
+
diff --git a/kcalc/version.h b/kcalc/version.h
new file mode 100644
index 0000000..9a591f3
--- /dev/null
+++ b/kcalc/version.h
@@ -0,0 +1 @@
+#define KCALCVERSION "2.0.6"