Initial import of qalculate-kde 0.9.7

r14.0.x
Slávek Banko 9 years ago
commit ee0c9d4bc3

@ -0,0 +1 @@
Niklas Knutsson <nq@altern.org>

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

@ -0,0 +1,477 @@
2009-01-05 Jonathan Stickel <jjstickel@vcn.com>
* General build updates and bug fixes, including the ability to
build against cln >= 1.2.
2007-08-07 Niklas Knutsson <nq@altern.org>
* New Simplified Chinese translation (Roy Qu <royqh1979@gmail.com>)
2007-04-26 Niklas Knutsson <nq@altern.org>
* Fix equals sign for comparison with approximately displayed value
2007-04-16 Niklas Knutsson <nq@altern.org>
* Always input decimal separator sign on keypad separator press
2007-03-21 Niklas Knutsson <nq@altern.org>
* Minor documentation fixes
2006-12-16 Niklas Knutsson <nq@altern.org>
* New French translation (Nicolas Laug <Nicolas.Laug@polymtl.ca>)
2006-11-18 Niklas Knutsson <nq@altern.org>
* Update Swedish translation
2006-11-07 Niklas Knutsson <nq@altern.org>
* Update Dutch translation (Jaap Woldringh <jjh.woldringh@planet.nl>)
2006-11-02 Niklas Knutsson <nq@altern.org>
* Connect "Exp" button Exp RPN operation and add Ctrl+Shift+E shortcut
2006-09-10 Niklas Knutsson <nq@altern.org>
* Ability to set shortcuts for meta modes
2006-09-05 Niklas Knutsson <nq@altern.org>
* Integer factorization
2006-07-19 Niklas Knutsson <nq@altern.org>
* "Include headings" -> "Includes headings"
2006-07-14 Niklas Knutsson <nq@altern.org>
* Fix set unknowns in RPN mode
2006-07-12 Niklas Knutsson <nq@altern.org>
* Fixes for old KDE and Qt version
2006-07-02 Niklas Knutsson <nq@altern.org>
* Global shortcut for show/hide
* Add "Engineering" to popup menu
* Make separate options for "Sort Minus Last" and "Negative Exponents" in numerical display menu
* Save history in a generic format as in qalculate-gtk
* Add "Edit Expression", "Edit Result", and "Insert Result Variable" to history context menu
* Do not put numerator in parenthesis in (1/2)/m, with "Place Units Separately" activated
* Increment version number
2006-06-20 Niklas Knutsson <nq@altern.org>
* Select text when editing matrix with F2 or Tab
2006-06-19 Niklas Knutsson <nq@altern.org>
* Use localized comma for insert matrix/vector
* Display parentheses correctly with flat division when "Place units separately" is activated
2006-06-16 Niklas Knutsson <nq@altern.org>
* Fix add/modify series on Enter in expression field
2006-06-10 Niklas Knutsson <nq@altern.org>
* Add "Engineering" display mode
2006-06-01 Niklas Knutsson <nq@altern.org>
* Polishing before 0.9.4 release
2006-05-20 Niklas Knutsson <nq@altern.org>
* Use icon buttons by default
2006-05-09 Niklas Knutsson <nq@altern.org>
* Use KLocale functions for decimal signs as, kde sets LC_NUMERIC to "C"
2006-04-30 Niklas Knutsson <nq@altern.org>
* "Convert to Best Unit" and "Convert to Base Units" was swapped
2006-04-28 Niklas Knutsson <nq@altern.org>
* Fix function editing with subfunctions
2006-04-23 Niklas Knutsson <nq@altern.org>
* Update documentation
* Update Swedish translation
2006-04-10 Niklas Knutsson <nq@altern.org>
* Align all matrix/vector table items right
* Do not calculate twice when dialog pops up
* Remember visible tab with rpn mode on and off
* Enhance matrix/vector dialogs
2006-04-09 Niklas Knutsson <nq@altern.org>
* Do not add empty expressions to expression entry history
* Fix keyboard input with focus on stack list
* Add buttons and switch single selection for the stack list
* Show default value of arguments in function description
2006-04-08 Niklas Knutsson <nq@altern.org>
* Improve RPN mode
* "Use only keypad keys for RPN operations" option
* Redirect all unused input to expression entry
* Tooltips on configure dialog
* Localize expressions in unit manager
* Options to use dot as thousands separator when it is not the default decimal sign
2006-04-06 Niklas Knutsson <nq@altern.org>
* Finish RPN mode
2006-04-04 Niklas Knutsson <nq@altern.org>
* True RPN mode
2006-04-02 Niklas Knutsson <nq@altern.org>
* Documentation updates
2006-04-01 Niklas Knutsson <nq@altern.org>
* Handle custom condition in edit argument dialog
2006-03-29 Niklas Knutsson <nq@altern.org>
* Focus text field that caused error after error message
* Fix edit dataset name
* Clear description and object list on data set deletion
2006-03-28 Niklas Knutsson <nq@altern.org>
* New icons
2006-03-27 Niklas Knutsson <nq@altern.org>
* Check capitalization
* Dutch translation
* Do not enable system tray icon by default
2006-03-23 Niklas Knutsson <nq@altern.org>
* Put selection of number base in result and expression in the same dialog
2006-03-20 Niklas Knutsson <nq@altern.org>
* Calculate selection (-clipboard, -c) command line option
2006-03-19 Niklas Knutsson <nq@altern.org>
* Use Escape key to hide window when tray icon is on
2006-03-18 Niklas Knutsson <nq@altern.org>
* Fix session management
* Enable system tray icon by default
2006-03-13 Niklas Knutsson <nq@altern.org>
* Do not do any unnecessary result updates when loading meta mode
* Show original parsed precision of enetered numbers
2006-02-11 Niklas Knutsson <nq@altern.org>
* Do not use "Read Precision" in plot
2006-02-07 Niklas Knutsson <nq@altern.org>
* "RPN Mode" -> "RPN Syntax"
2006-02-01 Niklas Knutsson <nq@altern.org>
* When in RPN mode, do not put selection in parenthesis and place operator after
2005-12-20 Niklas Knutsson <nq@altern.org>
* Warn about denominators assumed non-zero option
2005-12-19 Niklas Knutsson <nq@altern.org>
* Update Swedish translation
* Update documentation
2005-12-13 Niklas Knutsson <nq@altern.org>
* Set minimum with for entries in units dialog
2005-12-13 Niklas Knutsson <nq@altern.org>
* Display AND and OR with lower-case letters
2005-12-11 Niklas Knutsson <nq@altern.org>
* No double quotes in in history from set unknowns
2005-12-03 Niklas Knutsson <nq@altern.org>
* Display "x < 3 && x > 1" as "1 < x < 3"
2005-11-29 Niklas Knutsson <nq@altern.org>
* Do not display (x)(y)^z with multiplication sign
* No double quotes in set unknowns dialog
* Set max precision to 100000
2005-11-27 Niklas Knutsson <nq@altern.org>
* Update assumption menu items and combo boxes (in edit unknown variable dialog)
after setting sign or type (ex. setting sign to positive makes type at least real)
2005-11-26 Niklas Knutsson <nq@altern.org>
* Do not start command thread more than once
2005-11-24 Niklas Knutsson <nq@altern.org>
* Never display 1/x as (1)/x no matter how deeply nested
2005-11-22 Niklas Knutsson <nq@altern.org>
* Factorize and simplify in a separate thread that can be stopped and show progress dialog
* Clear history action and history popup menu item
* Allow factorization print option (for (3/4*(x+1))/(y+1))
* Fix cancel command called from popup menu (using QTimer::singleShot())
2005-11-19 Niklas Knutsson <nq@altern.org>
* Do not display colon when argument description is empty
2005-11-17 Niklas Knutsson <nq@altern.org>
* Simplify menu item
* Algebraic mode -- simplify, factorize, or none
2005-11-07 Niklas Knutsson <nq@altern.org>
* Do not remove white spaces from expression history
* Do not add plot expression with only white space
* Do not automatically add plot expression when applying appearance or function range
2005-11-06 Niklas Knutsson <nq@altern.org>
* Fix completion with or after unicode signs
2005-11-05 Niklas Knutsson <nq@altern.org>
* Fix parenthesis for division in division
2005-11-04 Niklas Knutsson <nq@altern.org>
* Fix compilation with --enable-final
2005-11-01 Niklas Knutsson <nq@altern.org>
* History enhancements
2005-10-31 Niklas Knutsson <nq@altern.org>
* Remove word wrap in result display
* Fix scaling (font size were replaced in the wrong order)
* Polishing
2005-10-30 Niklas Knutsson <nq@altern.org>
* Finish documentation updates
* Completion fixes
2005-10-29 Niklas Knutsson <nq@altern.org>
* Update parse status display of to unit expression and parse display in history
* Nicer history display with separating horizontal lines and italic parsed expression
2005-10-28 Niklas Knutsson <nq@altern.org>
* Update documentation
* Use option to reduce transformation when parsing and print formating for parse status
* Update recalculation behaviour on mode change
* Support for binary and other prefixes
2005-10-26 Niklas Knutsson <nq@altern.org>
* Add unit selector to convert to unit dialog
* Update Swedish translation
* Fix window height with menubar in window by making the minimum window size equal to the one line menubar width
* Reduce result display size on startup and expand history on resize
* Fix display of long parsed expression
2005-10-25 Niklas Knutsson <nq@altern.org>
* Completion fixes and enhancements
* Match against Calculator's item lists directly instead of passing names to KCompletion
* Completion for all names
* Disable completion for disabled object types (functions, variables and units)
* Show alternative names in cursive style after default in completion list
* Make suffixes in completion list smaller
* Option to disable completion
* Remove details buttons from variable edit dialog and instead hide value entry,
exact button and names details in variable edit dialog in store mode
* Use variables edit dialog also for storing matrix/vector results
* Fill in forgotten new data set function (for File->New->Data Set)
2005-10-24 Niklas Knutsson <nq@altern.org>
* Fix for QT_NO_STL
* Tweak layout and show functions button again, with italic f(x)
* Remove automatic accelerators from buttons in main window
* Remove mod button and move f(x) button to keypad
* Add option to enable/disable icon buttons
* Add apply button to preferences dialog
2005-10-23 Niklas Knutsson <nq@altern.org>
* QalculateButton class for smaller buttons and markup
* GUI redesign along the lines of redesigned the GTK+ GUI
* Fix tab order and use lower case letters for function buttons
* Use text instead of pixmaps for top-right buttons if not icons on buttons KDE option is turned on
* Polishing
2005-10-20 Niklas Knutsson <nq@altern.org>
* had_warnings_before = had_errors => had_warnings_before = had_warnings
* Configuration of status warning and error colors
* Split settings dialog in two tabs
2005-10-19 Niklas Knutsson <nq@altern.org>
* Ability to save different modes
* Update documentation
* Fix as-you-type function hints when unlimited number of arguments
* Increase max value length in variables dialog
* Font selection for status label
* Choice to disable as-you-type expression status
2005-10-18 Niklas Knutsson <nq@altern.org>
* Fix as-you-type parsing with " to " in expression
* Display as-you-type parsing with warnings in blue
2005-10-17 Niklas Knutsson <nq@altern.org>
* Display parsing and function hints under the expression entry to the left
* Fix recovery of expression after closed completion list
2005-10-11 Niklas Knutsson <nq@altern.org>
* Change alignment in entries in convert number bases dialog
2005-09-30 Niklas Knutsson <nq@altern.org>
* Fix round halfway numbers to even menu item
2005-09-25 Niklas Knutsson <nq@altern.org>
* Also process operators entered with keypad (ButtonState)
* Default to no system tray icon
2005-06-16 Niklas Knutsson <nq@altern.org>
* System tray icon and close to system tray option
2005-06-10 Niklas Knutsson <nq@altern.org>
* Add glib-2.0 and libxml-2.0 to PKG_CHECK_MODULES
* Display prefix in object info
* Check that prefix name can be displayed
* Right align equals label in units dialog
* Confirm overwriting result and plot image files
* Use KIO instead of wget for fetching exchange rates
* Close gnuplot and disable save button when no series defined
* Compile with kdelibs < 3.4
* Compile with Qt 3.1 and 3.2
2005-06-09 Niklas Knutsson <nq@altern.org>
* Use KLineEdit's popup menu and disable completion menu by temporarily setting the completion object to NULL
* Enable click-to-focus for result display
* Focus expression entry on most key events
* Focus expression entry on set result
* Act also on base combo activated
* Do not open matrix result twice
* Set close button default and focus in result matrix/vector dialog
* Insert selection button in matrix/vector dialog
* Use number base for expression parsing when printing parsed expression
* Add "No Prefix" to set prefix menu
* Support for "e" instead of "E" in result
* Enhance progress dialogs
2005-06-08 Niklas Knutsson <nq@altern.org>
* Combo box simple numerical display activated normal display
* Do not cover function arguments by function anchor to avoid formatting problems
* Display correct equals in history on updated display format
* Add space also around SIGN_DIVISION_SLASH as it seems to look best for most fonts (except Bitstream Cyberbit)
* Use the QalculateExpressionEdit widget in the plot dialog
* Place reference to MathStructure in anchor instead of object name
* Add show parsed expression and show object info to result display context menu
* Insert matrix/vector dialog from menu and result display
* Double click action in result display
* Matrix and vector buttons in insert function dialog
* Open selected expression in insert matrix/vector dialog
2005-06-07 Niklas Knutsson <nq@altern.org>
* Hide completion when expression is empty
* Handle input keys ^+digit as "^"+digit
* Handle input keys ^+0 as degree sign
* Update screenshots in documentation
* Convert button behaviour should depend on keyboard focus
* Let return/enter activate convert instead of a default button
2005-06-06 Niklas Knutsson <nq@altern.org>
* Do not recreate the division line image every time
* Add web address to about data and change bug address
2005-06-05 Niklas Knutsson <nq@altern.org>
* Disable list view sorting correctly
* Set name in argument edit dialog
* Align yes/no columns center
* Add list items add the end of the list to get the right order
* Add tooltips
* There is really no reason to untoggle hyp and inv automatically
* Use qalculate_kde instead of qalculate-kde for everything but the binary to please kde
* Reload also recent composite units and getActive...
* Result display is more efficient than in qalculate-gtk so no need for "result is too long"
* Do not put extra space a the top of result is more than one row
* Bitwise NOT (~)
* xor() and bitXor()
2005-06-04 Niklas Knutsson <nq@altern.org>
* Update base menu when opening other base dialog even when the spinbox value equals the current base
* Base and numeric mode combo boxes should not be editable
* Make set other base non-radio action and use listBox()->selected() for
base in keypad to get signal on reselection of other base
* Put object creation in slotOk() instead of using exec() in a loop
2005-06-03 Niklas Knutsson <nq@altern.org>
* Assume that QT does not have STL support -- always use c_str() and ascii()
* Bitwise AND (&), OR (|), XOR
* Remove old giac stuff
* Use KUniqueApplication
* Shift GUI vertical orientation and increase right display margin
* stripWhiteSpace() returns a new string!
2005-06-02 Niklas Knutsson <nq@altern.org>
* Clean up plot dialog on finished() instead of hidden()
* Try to align the result vertically more in the middle
* Display ampersands in menus for categorys and titles

@ -0,0 +1,167 @@
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes a while. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Type `make install' to install the programs and any data files and
documentation.
4. You can remove the program binaries and object files from the
source code directory by typing `make clean'.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made.
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.

@ -0,0 +1,22 @@
SUBDIRS = $(TOPSUBDIRS)
$(top_srcdir)/configure.in: configure.in.in $(top_srcdir)/subdirs
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.in ;
$(top_srcdir)/subdirs:
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs
$(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in
@cd $(top_srcdir) && cat admin/acinclude.m4.in admin/libtool.m4.in > acinclude.m4
MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 configure.files
package-messages:
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common package-messages
$(MAKE) -C po merge
EXTRA_DIST = admin COPYING configure.in.in
dist-hook:
cd $(top_distdir) && perl admin/am_edit -padmin
cd $(top_distdir) && $(MAKE) -f admin/Makefile.common subdirs

@ -0,0 +1,10 @@
all:
@echo "This Makefile is only for the CVS repository"
@echo "This will be deleted before making the distribution"
@echo ""
$(MAKE) -f admin/Makefile.common cvs
dist:
$(MAKE) -f admin/Makefile.common dist
.SILENT:

@ -0,0 +1,20 @@
#MIN_CONFIG(3.1.0)
AM_INIT_AUTOMAKE(qalculate_kde, 0.9.7)
AC_C_BIGENDIAN
AC_CHECK_KDEMAXPATHLEN
AC_CHECK_LIB(pthread, pthread_create, [LIBS="$LIBS -lpthread"])
AC_LANG([C++])
PKG_CHECK_MODULES(QALCULATE, [
libqalculate >= 0.9.7
])
AC_SUBST(QALCULATE_CFLAGS)
AC_SUBST(QALCULATE_LIBS)
LIBS="$LIBS $QALCULATE_LIBS"
CFLAGS="$CFLAGS $QALCULATE_CFLAGS"
CPPFLAGS="$CPPFLAGS $QALCULATE_CFLAGS"
CXXFLAGS="$CXXFLAGS $USE_EXCEPTIONS"

@ -0,0 +1,4 @@
# the SUBDIRS is filled automatically by am_edit. If files are
# in this directory they are installed into the english dir
SUBDIRS = en

@ -0,0 +1,4 @@
# the SUBDIRS is filled automatically by am_edit. If files are
# in this directory they are installed into the english dir
SUBDIRS = qalculate_kde

@ -0,0 +1,2 @@
KDE_DOCS = AUTO
KDE_LANG = en

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

@ -0,0 +1,631 @@
<appendix id="qalculate-definitions-variables">
<title>Variable List</title>
<sect1 id="qalculate-definitions-variables-1-Basic-Constants">
<title>Basic Constants</title>
<table id="qalculate-TBL-variables-Basic-Constants" frame="topbot" colsep="1">
<title>Variables: Basic Constants</title>
<tgroup cols="3" colsep="1" rowsep="0">
<colspec colname="COLSPEC0"/>
<colspec colname="COLSPEC1"/>
<colspec colname="COLSPEC2"/>
<thead>
<row valign="top">
<entry colname="COLSPEC0"><para>Title</para></entry>
<entry colname="COLSPEC1"><para>Names</para></entry>
<entry colname="COLSPEC2"><para>Value</para></entry>
</row>
</thead>
<tbody>
<row valign="top">
<entry><para>Apery's Constant</para></entry>
<entry><para>apery</para></entry>
<entry><para>zeta(3)</para></entry>
</row>
<row valign="top">
<entry><para>Archimede's Constant (pi)</para></entry>
<entry><para>π / pi</para></entry>
<entry><para>3.1415927 (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Catalan's Constant</para></entry>
<entry><para>catalan</para></entry>
<entry><para>0.91596559 (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Euler's Constant</para></entry>
<entry><para>γ / euler</para></entry>
<entry><para>0.57721566 (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Pythagora's Constant (sqrt 2)</para></entry>
<entry><para>pythagoras</para></entry>
<entry><para>sqrt(2)</para></entry>
</row>
<row valign="top">
<entry><para>The Base of Natural Logarithms (e)</para></entry>
<entry><para>e</para></entry>
<entry><para>2.7182818 (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>The Golden Ratio</para></entry>
<entry><para>golden / φ</para></entry>
<entry><para>(1+sqrt(5))/2</para></entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="qalculate-definitions-variables-1-Large-Numbers">
<title>Large Numbers</title>
<table id="qalculate-TBL-variables-Large-Numbers" frame="topbot" colsep="1">
<title>Variables: Large Numbers</title>
<tgroup cols="3" colsep="1" rowsep="0">
<colspec colname="COLSPEC0"/>
<colspec colname="COLSPEC1"/>
<colspec colname="COLSPEC2"/>
<thead>
<row valign="top">
<entry colname="COLSPEC0"><para>Title</para></entry>
<entry colname="COLSPEC1"><para>Names</para></entry>
<entry colname="COLSPEC2"><para>Value</para></entry>
</row>
</thead>
<tbody>
<row valign="top">
<entry><para>Billion</para></entry>
<entry><para>billion</para></entry>
<entry><para>1E9</para></entry>
</row>
<row valign="top">
<entry><para>Centillion</para></entry>
<entry><para>centillion</para></entry>
<entry><para>1E303</para></entry>
</row>
<row valign="top">
<entry><para>Decillion</para></entry>
<entry><para>decillion</para></entry>
<entry><para>1E33</para></entry>
</row>
<row valign="top">
<entry><para>Duodecillion</para></entry>
<entry><para>duodecillion</para></entry>
<entry><para>1E39</para></entry>
</row>
<row valign="top">
<entry><para>Googol</para></entry>
<entry><para>googol</para></entry>
<entry><para>10^100</para></entry>
</row>
<row valign="top">
<entry><para>Googolplex</para></entry>
<entry><para>googolplex</para></entry>
<entry><para>10^(10^100)</para></entry>
</row>
<row valign="top">
<entry><para>Hundred</para></entry>
<entry><para>hundred</para></entry>
<entry><para>1E2</para></entry>
</row>
<row valign="top">
<entry><para>Million</para></entry>
<entry><para>million</para></entry>
<entry><para>1E6</para></entry>
</row>
<row valign="top">
<entry><para>Nonillion</para></entry>
<entry><para>nonillion</para></entry>
<entry><para>1E30</para></entry>
</row>
<row valign="top">
<entry><para>Novemdecillion</para></entry>
<entry><para>novemdecillion</para></entry>
<entry><para>1E60</para></entry>
</row>
<row valign="top">
<entry><para>Octillion</para></entry>
<entry><para>octillion</para></entry>
<entry><para>1E27</para></entry>
</row>
<row valign="top">
<entry><para>Octodecillion</para></entry>
<entry><para>octodecillion</para></entry>
<entry><para>1E57</para></entry>
</row>
<row valign="top">
<entry><para>Quadrillion</para></entry>
<entry><para>quadrillion</para></entry>
<entry><para>1E15</para></entry>
</row>
<row valign="top">
<entry><para>Quattuordecillion</para></entry>
<entry><para>quattuordecillion</para></entry>
<entry><para>1E45</para></entry>
</row>
<row valign="top">
<entry><para>Quindecillion</para></entry>
<entry><para>quindecillion</para></entry>
<entry><para>1E48</para></entry>
</row>
<row valign="top">
<entry><para>Quintillion</para></entry>
<entry><para>quintillion</para></entry>
<entry><para>1E18</para></entry>
</row>
<row valign="top">
<entry><para>Septendecillion</para></entry>
<entry><para>septendecillion</para></entry>
<entry><para>1E54</para></entry>
</row>
<row valign="top">
<entry><para>Septillion</para></entry>
<entry><para>septillion</para></entry>
<entry><para>1E24</para></entry>
</row>
<row valign="top">
<entry><para>Sexdecillion</para></entry>
<entry><para>sexdecillion</para></entry>
<entry><para>1E51</para></entry>
</row>
<row valign="top">
<entry><para>Sextillion</para></entry>
<entry><para>sextillion</para></entry>
<entry><para>1E21</para></entry>
</row>
<row valign="top">
<entry><para>Thousand</para></entry>
<entry><para>thousand</para></entry>
<entry><para>1E3</para></entry>
</row>
<row valign="top">
<entry><para>Tredecillion</para></entry>
<entry><para>tredecillion</para></entry>
<entry><para>1E42</para></entry>
</row>
<row valign="top">
<entry><para>Trillion</para></entry>
<entry><para>trillion</para></entry>
<entry><para>1E12</para></entry>
</row>
<row valign="top">
<entry><para>Undecillion</para></entry>
<entry><para>undecillion</para></entry>
<entry><para>1E36</para></entry>
</row>
<row valign="top">
<entry><para>Vigintillion</para></entry>
<entry><para>vigintillion</para></entry>
<entry><para>1E63</para></entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="qalculate-definitions-variables-1-Physical-Constants">
<title>Physical Constants</title>
<sect2 id="qalculate-definitions-variables-2-Atomic-and-Nuclear-Constants">
<title>Atomic and Nuclear Constants</title>
<table id="qalculate-TBL-variables-Atomic-and-Nuclear-Constants" frame="topbot" colsep="1">
<title>Variables: Atomic and Nuclear Constants</title>
<tgroup cols="3" colsep="1" rowsep="0">
<colspec colname="COLSPEC0"/>
<colspec colname="COLSPEC1"/>
<colspec colname="COLSPEC2"/>
<thead>
<row valign="top">
<entry colname="COLSPEC0"><para>Title</para></entry>
<entry colname="COLSPEC1"><para>Names</para></entry>
<entry colname="COLSPEC2"><para>Value</para></entry>
</row>
</thead>
<tbody>
<row valign="top">
<entry><para>Alpha Particle Mass</para></entry>
<entry><para>alpha_particle_mass / m_α</para></entry>
<entry><para>6.6446565E-24*g (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Bohr Radius</para></entry>
<entry><para>bohr_radius / a_o</para></entry>
<entry><para>0.5291772108E-10*m (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Classical Electron Radius</para></entry>
<entry><para>classical_electron_radius / r_e</para></entry>
<entry><para>2.817940325E-15*m (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Compton Wavelength</para></entry>
<entry><para>compton_wavelength / λ_C</para></entry>
<entry><para>2.426310238E-12*m (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Electron Mass</para></entry>
<entry><para>electron_mass / m_e</para></entry>
<entry><para>9.1093826E-28*g (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Helion Mass</para></entry>
<entry><para>helion_mass / m_h</para></entry>
<entry><para>5.00641214E-24*g (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Neutron Mass</para></entry>
<entry><para>neutron_mass / m_n</para></entry>
<entry><para>1.67492728E-24*g (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Proton Mass</para></entry>
<entry><para>proton_mass / m_p</para></entry>
<entry><para>1.67262171E-24*g (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Rydberg Constant</para></entry>
<entry><para>rydberg / R_∞</para></entry>
<entry><para>10973731.568525*m^(-1) (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Tau Mass</para></entry>
<entry><para>tau_mass / m_τ</para></entry>
<entry><para>3.16777E-24*g (approximate)</para></entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
<sect2 id="qalculate-definitions-variables-2-Electromagnetic-Constants">
<title>Electromagnetic Constants</title>
<table id="qalculate-TBL-variables-Electromagnetic-Constants" frame="topbot" colsep="1">
<title>Variables: Electromagnetic Constants</title>
<tgroup cols="3" colsep="1" rowsep="0">
<colspec colname="COLSPEC0"/>
<colspec colname="COLSPEC1"/>
<colspec colname="COLSPEC2"/>
<thead>
<row valign="top">
<entry colname="COLSPEC0"><para>Title</para></entry>
<entry colname="COLSPEC1"><para>Names</para></entry>
<entry colname="COLSPEC2"><para>Value</para></entry>
</row>
</thead>
<tbody>
<row valign="top">
<entry><para>Borh Magneton</para></entry>
<entry><para>bohr_magneton / μ_B</para></entry>
<entry><para>927.400949E-26*J*T^(-1) (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Conductance Quantum</para></entry>
<entry><para>conductance_quantum / G_0</para></entry>
<entry><para>7.748091733E-5*S (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Elementary Charge</para></entry>
<entry><para>elementary_charge / e_charge</para></entry>
<entry><para>1.60217653E-19*C (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Josephson Constant</para></entry>
<entry><para>josephson / K_J</para></entry>
<entry><para>483597.879E9*Hz*V^(-1) (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Magnetic Flux Quantum</para></entry>
<entry><para>magnetic_flux_quantum / Φ_0</para></entry>
<entry><para>2.06783372E-15*Wb (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Nuclear Magneton</para></entry>
<entry><para>nuclear_magneton / μ_N</para></entry>
<entry><para>5.05078343E-27*J*T^(-1) (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>von Klitzing Constant</para></entry>
<entry><para>klitzing / R_K</para></entry>
<entry><para>25812.807449*ohm (approximate)</para></entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
<sect2 id="qalculate-definitions-variables-2-Physico-Chemical-Constants">
<title>Physico-Chemical Constants</title>
<table id="qalculate-TBL-variables-Physico-Chemical-Constants" frame="topbot" colsep="1">
<title>Variables: Physico-Chemical Constants</title>
<tgroup cols="3" colsep="1" rowsep="0">
<colspec colname="COLSPEC0"/>
<colspec colname="COLSPEC1"/>
<colspec colname="COLSPEC2"/>
<thead>
<row valign="top">
<entry colname="COLSPEC0"><para>Title</para></entry>
<entry colname="COLSPEC1"><para>Names</para></entry>
<entry colname="COLSPEC2"><para>Value</para></entry>
</row>
</thead>
<tbody>
<row valign="top">
<entry><para>Atomic Mass Constant</para></entry>
<entry><para>atomic_mass / m_u</para></entry>
<entry><para>1.66053886E-24*g (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Avogadro Constant</para></entry>
<entry><para>avogadro / N_A</para></entry>
<entry><para>6.0221415E23*mol^(-1) (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Boltzmann Constant</para></entry>
<entry><para>boltzmann</para></entry>
<entry><para>1.3806505E-23*J*K^(-1) (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Faraday Constant</para></entry>
<entry><para>faraday</para></entry>
<entry><para>96485.3383*C*mol^(-1) (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>First Radiation Constant</para></entry>
<entry><para>first_radiation / c_1</para></entry>
<entry><para>3.74177138E-16*W*m^2 (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Ideal Gas Constant</para></entry>
<entry><para>ideal_gas</para></entry>
<entry><para>8.314472*J*K^(-1)*mol^(-1) (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Second Radiation Constant</para></entry>
<entry><para>second_radiation / c_2</para></entry>
<entry><para>1.4387752E-2*m*K (approximate)</para></entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
<sect2 id="qalculate-definitions-variables-2-Universal-Constants">
<title>Universal Constants</title>
<table id="qalculate-TBL-variables-Universal-Constants" frame="topbot" colsep="1">
<title>Variables: Universal Constants</title>
<tgroup cols="3" colsep="1" rowsep="0">
<colspec colname="COLSPEC0"/>
<colspec colname="COLSPEC1"/>
<colspec colname="COLSPEC2"/>
<thead>
<row valign="top">
<entry colname="COLSPEC0"><para>Title</para></entry>
<entry colname="COLSPEC1"><para>Names</para></entry>
<entry colname="COLSPEC2"><para>Value</para></entry>
</row>
</thead>
<tbody>
<row valign="top">
<entry><para>Characteristic Impedance of Vacuum</para></entry>
<entry><para>characteristic_impedance / Z_0</para></entry>
<entry><para>4E-7*pi*299792458*ohm</para></entry>
</row>
<row valign="top">
<entry><para>Electric Constant (Permittivity of Free Space)</para></entry>
<entry><para>electric_constant / ε_0</para></entry>
<entry><para>1/(4E-7*pi*299792458^2)*F*m^(-1)</para></entry>
</row>
<row valign="top">
<entry><para>Magnetic Constant (Permeability of Free Space)</para></entry>
<entry><para>magnetic_constant / μ_0</para></entry>
<entry><para>4E-7*pi*N*A^(-2)</para></entry>
</row>
<row valign="top">
<entry><para>Newtonian Constant of Gravitation</para></entry>
<entry><para>newtonian_constant / G</para></entry>
<entry><para>6.6742E-11*m^3*kg^(-1)*s^(-2) (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Planck Constant</para></entry>
<entry><para>planck</para></entry>
<entry><para>6.6260693E-34*J*s (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Planck Constant over 2 pi</para></entry>
<entry><para>planck2pi</para></entry>
<entry><para>planck/(2*pi)</para></entry>
</row>
<row valign="top">
<entry><para>Planck Length</para></entry>
<entry><para>planck_length / l_P</para></entry>
<entry><para>1.61624E-35*m (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Planck Mass</para></entry>
<entry><para>planck_mass / m_P</para></entry>
<entry><para>2.17645E-5*g (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Planck Temperature</para></entry>
<entry><para>planck_temperature / T_P</para></entry>
<entry><para>1.41679E32*K (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Planck Time</para></entry>
<entry><para>planck_time / t_P</para></entry>
<entry><para>5.39121E-44*s (approximate)</para></entry>
</row>
<row valign="top">
<entry><para>Speed of Light in Vacuum</para></entry>
<entry><para>c / speed_of_light</para></entry>
<entry><para>299792458*m*s^(-1)</para></entry>
</row>
</tbody>
</tgroup>
</table>
</sect2>
</sect1>
<sect1 id="qalculate-definitions-variables-1-Small-Numbers">
<title>Small Numbers</title>
<table id="qalculate-TBL-variables-Small-Numbers" frame="topbot" colsep="1">
<title>Variables: Small Numbers</title>
<tgroup cols="3" colsep="1" rowsep="0">
<colspec colname="COLSPEC0"/>
<colspec colname="COLSPEC1"/>
<colspec colname="COLSPEC2"/>
<thead>
<row valign="top">
<entry colname="COLSPEC0"><para>Title</para></entry>
<entry colname="COLSPEC1"><para>Names</para></entry>
<entry colname="COLSPEC2"><para>Value</para></entry>
</row>
</thead>
<tbody>
<row valign="top">
<entry><para>Per Mille</para></entry>
<entry><para>permille / ‰</para></entry>
<entry><para>1/1000</para></entry>
</row>
<row valign="top">
<entry><para>Per Myriad</para></entry>
<entry><para>permyriad / ‱</para></entry>
<entry><para>1/10000</para></entry>
</row>
<row valign="top">
<entry><para>Procent</para></entry>
<entry><para>% / procent</para></entry>
<entry><para>1/100</para></entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="qalculate-definitions-variables-1-Special-Numbers">
<title>Special Numbers</title>
<table id="qalculate-TBL-variables-Special-Numbers" frame="topbot" colsep="1">
<title>Variables: Special Numbers</title>
<tgroup cols="3" colsep="1" rowsep="0">
<colspec colname="COLSPEC0"/>
<colspec colname="COLSPEC1"/>
<colspec colname="COLSPEC2"/>
<thead>
<row valign="top">
<entry colname="COLSPEC0"><para>Title</para></entry>
<entry colname="COLSPEC1"><para>Names</para></entry>
<entry colname="COLSPEC2"><para>Value</para></entry>
</row>
</thead>
<tbody>
<row valign="top">
<entry><para>False</para></entry>
<entry><para>false / no</para></entry>
<entry><para>0</para></entry>
</row>
<row valign="top">
<entry><para>Imaginary i (sqrt -1)</para></entry>
<entry><para>i</para></entry>
<entry><para>i</para></entry>
</row>
<row valign="top">
<entry><para>Infinity</para></entry>
<entry><para>infinity</para></entry>
<entry><para>infinity</para></entry>
</row>
<row valign="top">
<entry><para>Negative Infinity</para></entry>
<entry><para>minus_infinity</para></entry>
<entry><para>-(+infinity)</para></entry>
</row>
<row valign="top">
<entry><para>Positive Infinity</para></entry>
<entry><para>plus_infinity</para></entry>
<entry><para>(+infinity)</para></entry>
</row>
<row valign="top">
<entry><para>True</para></entry>
<entry><para>true / yes</para></entry>
<entry><para>1</para></entry>
</row>
<row valign="top">
<entry><para>Undefined</para></entry>
<entry><para>undefined</para></entry>
<entry><para>undefined</para></entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="qalculate-definitions-variables-1-Temporary">
<title>Temporary</title>
<table id="qalculate-TBL-variables-Temporary" frame="topbot" colsep="1">
<title>Variables: Temporary</title>
<tgroup cols="3" colsep="1" rowsep="0">
<colspec colname="COLSPEC0"/>
<colspec colname="COLSPEC1"/>
<colspec colname="COLSPEC2"/>
<thead>
<row valign="top">
<entry colname="COLSPEC0"><para>Title</para></entry>
<entry colname="COLSPEC1"><para>Names</para></entry>
<entry colname="COLSPEC2"><para>Value</para></entry>
</row>
</thead>
<tbody>
<row valign="top">
<entry><para>Answer 2</para></entry>
<entry><para>ans2</para></entry>
<entry><para>a previous result</para></entry>
</row>
<row valign="top">
<entry><para>Answer 3</para></entry>
<entry><para>ans3</para></entry>
<entry><para>a previous result</para></entry>
</row>
<row valign="top">
<entry><para>Answer 4</para></entry>
<entry><para>ans4</para></entry>
<entry><para>a previous result</para></entry>
</row>
<row valign="top">
<entry><para>Answer 5</para></entry>
<entry><para>ans5</para></entry>
<entry><para>a previous result</para></entry>
</row>
<row valign="top">
<entry><para>Last Answer</para></entry>
<entry><para>ans / answer / ans1</para></entry>
<entry><para>a previous result</para></entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
<sect1 id="qalculate-definitions-variables-1-Unknowns">
<title>Unknowns</title>
<table id="qalculate-TBL-variables-Unknowns" frame="topbot" colsep="1">
<title>Variables: Unknowns</title>
<tgroup cols="3" colsep="1" rowsep="0">
<colspec colname="COLSPEC0"/>
<colspec colname="COLSPEC1"/>
<colspec colname="COLSPEC2"/>
<thead>
<row valign="top">
<entry colname="COLSPEC0"><para>Title</para></entry>
<entry colname="COLSPEC1"><para>Names</para></entry>
<entry colname="COLSPEC2"><para>Value</para></entry>
</row>
</thead>
<tbody>
<row valign="top">
<entry><para>x</para></entry>
<entry><para>x</para></entry>
<entry><para>default assumptions</para></entry>
</row>
<row valign="top">
<entry><para>y</para></entry>
<entry><para>y</para></entry>
<entry><para>default assumptions</para></entry>
</row>
<row valign="top">
<entry><para>z</para></entry>
<entry><para>z</para></entry>
<entry><para>default assumptions</para></entry>
</row>
</tbody>
</tgroup>
</table>
</sect1>
</appendix>

@ -0,0 +1,2 @@
POFILES = AUTO

2639
po/fr.po

File diff suppressed because it is too large Load Diff

2634
po/nl.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2615
po/sv.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,58 @@
# set the include path for X, qt and KDE
INCLUDES = $(all_includes)
# these are the headers for your project
# let automoc handle all of the meta source files (moc)
METASOURCES = AUTO
messages: rc.cpp
$(EXTRACTRC) `find . -name \*.ui -o -name \*.rc` > rc.cpp
$(XGETTEXT) *.cpp -o $(podir)/qalculate_kde.pot
KDE_ICON = AUTO
#########################################################################
# APPLICATION SECTION
#########################################################################
# this is the program that gets installed. it's name is used for all
# of the other Makefile.am variables
bin_PROGRAMS = qalculate-kde
# the application source, library search path, and link libraries
qalculate_kde_SOURCES = buttonwithindexsignal.cpp kqalculate.cpp \
main.cpp preferences.cpp qalculatebuttonwithdata.cpp qalculateconvertnumberbasesdialog.cpp \
qalculateconvertunitsdialog.cpp qalculatedatasetsdialog.cpp qalculatedecimalsdialog.cpp qalculateeditdataobjectdialog.cpp \
qalculateeditdatasetdialog.cpp qalculateeditfunctiondialog.cpp qalculateeditmatrixvectordialog.cpp qalculateeditnamesdialog.cpp \
qalculateeditunitdialog.cpp qalculateeditunknownvariabledialog.cpp qalculateeditvariabledialog.cpp qalculateexportcsvdialog.cpp \
qalculateexpressionedit.cpp qalculatefunctionsdialog.cpp qalculateimportcsvdialog.cpp qalculateinsertfunctiondialog.cpp \
qalculateinsertmatrixvectordialog.cpp qalculate_kde_utils.cpp qalculateperiodictabledialog.cpp qalculateplotdialog.cpp \
qalculateprecisiondialog.cpp qalculatepreferencesdialog.cpp qalculatesetbasedialog.cpp \
qalculateunitsdialog.cpp qalculatevariablesdialog.cpp qalculateresultdisplay.cpp
qalculate_kde_LDFLAGS = $(KDE_RPATH) $(all_libraries)
qalculate_kde_LDADD = $(LIB_KDEUI) $(LIB_KIO)
# this is where the desktop file will go
shelldesktopdir = $(xdg_appsdir)
shelldesktop_DATA = qalculate_kde.desktop
# this is where the shell's XML-GUI resource file goes
shellrcdir = $(kde_datadir)/qalculate_kde
shellrc_DATA = qalculate_kdeui.rc
noinst_HEADERS = preferences.h qalculateinsertfunctiondialog.h qalculateinsertmatrixvectordialog.h \
buttonwithindexsignal.h qalculateexpressionedit.h qalculateconvertnumberbasesdialog.h \
qalculatebuttonwithdata.h qalculatesetbasedialog.h \
qalculatevariablesdialog.h qalculatefunctionsdialog.h qalculateunitsdialog.h \
qalculateeditunknownvariabledialog.h qalculatedecimalsdialog.h qalculateconvertunitsdialog.h \
qalculateprecisiondialog.h qalculateeditunitdialog.h qalculateeditnamesdialog.h \
qalculateeditfunctiondialog.h qalculateplotdialog.h qalculateimportcsvdialog.h \
qalculateexportcsvdialog.h qalculatepreferencesdialog.h qalculateeditmatrixvectordialog.h \
qalculatedatasetsdialog.h qalculateeditdatasetdialog.h qalculateeditdataobjectdialog.h \
qalculateresultdisplay.h
install-exec-local:
cd $(DESTDIR)$(bindir) && rm -f qalculate; $(LN_S) qalculate-kde qalculate

@ -0,0 +1,31 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "buttonwithindexsignal.h"
ButtonWithIndexSignal::ButtonWithIndexSignal(const QString & text, int index, QWidget *parent, const char *name) : QPushButton(text, parent, name) {
i = index;
connect(this, SIGNAL(clicked()), this, SLOT(emitClickedWithIndex()));
}
ButtonWithIndexSignal::~ButtonWithIndexSignal() {}
void ButtonWithIndexSignal::emitClickedWithIndex() {
emit clickedWithIndex(i);
}
#include "buttonwithindexsignal.moc"

@ -0,0 +1,39 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef BUTTONWITHINDEXSIGNAL_H
#define BUTTONWITHINDEXSIGNAL_H
#include <qpushbutton.h>
class ButtonWithIndexSignal : public QPushButton {
Q_OBJECT
public:
ButtonWithIndexSignal(const QString & text, int index, QWidget *parent = 0, const char *name = 0);
virtual ~ButtonWithIndexSignal();
int i;
public slots:
void emitClickedWithIndex();
signals:
void clickedWithIndex(int);
};
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 664 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

File diff suppressed because it is too large Load Diff

@ -0,0 +1,593 @@
/***************************************************************************
* Copyright (C) 2005-2007 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef KQALCULATE_H
#define KQALCULATE_H
#include <qvariant.h>
#include <kmainwindow.h>
#include <qvaluevector.h>
#include <qlabel.h>
#include <qpushbutton.h>
#include <qstylesheet.h>
#include <ktextbrowser.h>
#include <klistview.h>
#include <kdialogbase.h>
#include <kshortcut.h>
class Prefix;
class QalculatePrecisionDialog;
class Variable;
class MathFunction;
class Unit;
class QalculateDecimalsDialog;
class QalculateEditVariableDialog;
class QalculateEditMatrixVectorDialog;
class QalculateEditUnitDialog;
class QalculateEditFunctionDialog;
class QalculateEditDataSetDialog;
class QalculateEditUnknownVariableDialog;
class QalculateVariablesDialog;
class QalculateFunctionsDialog;
class QalculateUnitsDialog;
class QalculateDataSetsDialog;
class QalculateConvertUnitsDialog;
class KAction;
class KRadioAction;
class KToggleAction;
class QToolBar;
class QPopupMenu;
class KPushButton;
class QalculateExpressionEdit;
class QalculateResultDisplay;
class QFrame;
class QWidgetStack;
class QWidget;
class QComboBox;
class QalculateHistoryBrowser;
class QalculateConvertNumberBasesDialog;
class QalculatePeriodicTableDialog;
class QalculatePlotDialog;
class QalculateSetBaseDialog;
class KLineEdit;
class MathStructure;
class QalculateImportCSVDialog;
class QalculateExportCSVDialog;
class QalculatePreferencesDialog;
class QalculateInsertMatrixVectorDialog;
class KSystemTray;
class QalculateParseLabel;
class QButtonGroup;
class QRadioButton;
class QalculateButton;
class QVBoxLayout;
class KSeparator;
class KUniqueApplication;
class KConfig;
class QListViewItem;
class QalculateRPNStackListView;
class KGlobalAccel;
class KKeyButton;
void *view_proc(void *pipe);
void *command_proc(void *pipe);
enum {
COMMAND_FACTORIZE,
COMMAND_SIMPLIFY
};
class ModeObject : public QObject {
Q_OBJECT
public:
ModeObject(int mode);
int i_mode;
public slots:
void loadMode();
};
class KQalculate : public KMainWindow {
Q_OBJECT
public:
KQalculate(KUniqueApplication *parent = 0, const char* name = 0, WFlags fl = WType_TopLevel | WDestructiveClose);
virtual ~KQalculate();
void setupActions();
void setAssumptionsMenu();
void setModeActions();
void execute_expression(bool force = true);
void setResult(Prefix *prefix = NULL, bool update_history = true, bool update_parse = false, bool force = false, QString transformation = "", size_t stack_index = 0, bool register_moved = false);
void executeCommand(int command_type);
void result_display_updated();
void result_format_updated();
void result_action_executed();
void result_prefix_changed(Prefix *prefix = NULL);
void expression_calculation_updated();
void expression_format_updated(bool recalculate = false);
void display_errors(QString *new_text = NULL, int *inhistory_index = NULL);
void update_status_text();
void display_function_hint(MathFunction *f, int arg_index = 1);
void clearresult();
void create_fmenu();
void create_vmenu();
void create_umenu();
void create_toumenu();
void create_setpmenu();
void recreate_recent_functions();
void recreate_recent_variables();
void recreate_recent_units();
void function_inserted(MathFunction *object);
void variable_inserted(Variable *object);
void unit_inserted(Unit *object);
void updateStatusLabelFonts();
void set_unicode_buttons();
void insertButtonFunction(QString text, bool append_space = true);
void insertButtonFunction(MathFunction *f);
const MathStructure *getResultPart(int);
void insertMatrixVector(const MathStructure *m = NULL, bool do_vector = false, bool is_text_struct = false, bool is_result = false);
void calculateRPN(int op);
void calculateRPN(MathFunction *f);
void RPNStackEnter(Variable *v);
void RPNRegisterAdded(const QString &text, size_t index = 0);
void RPNRegisterRemoved(size_t index);
void RPNRegisterChanged(const QString &text, size_t index = 0);
QalculateInsertMatrixVectorDialog *insert_matrix_dialog;
QalculatePrecisionDialog *precisionDialog;
QalculateDecimalsDialog *decimalsDialog;
QalculateConvertUnitsDialog *convert_to_unit_expression_dialog;
QalculateEditVariableDialog *variable_edit_dialog, *store_dialog;
QalculateEditMatrixVectorDialog *matrix_edit_dialog;
QalculateEditUnitDialog *unit_edit_dialog;
QalculateEditFunctionDialog *function_edit_dialog;
QalculateEditDataSetDialog *dataset_edit_dialog;
QalculateEditUnknownVariableDialog *unknown_edit_dialog;
QalculateVariablesDialog *variables_dialog;
QalculateFunctionsDialog *functions_dialog;
QalculateUnitsDialog *units_dialog;
QalculateDataSetsDialog *datasets_dialog;
QalculateConvertNumberBasesDialog *convert_number_bases_dialog;
QalculatePeriodicTableDialog *periodic_table_dialog;
QalculateImportCSVDialog *import_csv_dialog;
QalculateExportCSVDialog *export_csv_dialog;
QalculatePlotDialog *plot_dialog;
QalculateSetBaseDialog *set_base_dialog;
QalculatePreferencesDialog *preferences_dialog;
QMap <int, Variable*> menu_variables_ids;
QMap <int, MathFunction*> menu_functions_ids;
QMap <int, Unit*> menu_units_ids, menu_to_unit_ids;
QMap <int, Prefix*> menu_units_prefixes_ids, menu_set_prefix_ids;
QValueVector<int> recent_function_ids;
QValueVector<int> recent_variable_ids;
QValueVector<int> recent_unit_ids;
QalculateRPNStackListView *stackList;
QVBoxLayout *stackPageButtonsLayout;
QalculateButton *registerUpButton, *registerDownButton, *deleteRegisterButton, *editRegisterButton, *clearStackButton;
QPopupMenu *stackMenu;
KUniqueApplication *m_parent;
KSystemTray *trayicon;
QalculateButton *executeButton, *storeButton, *convertButton;
QalculateButton *functionsButton;
QVBoxLayout *leftButtonsLayout;
KSeparator *leftButtonsSeparator;
QalculateExpressionEdit* expressionEdit;
QLabel *statusLabel_r;
QalculateParseLabel *statusLabel_l;
QalculateResultDisplay* resultLabel;
QWidgetStack* mainStack;
QFrame *bottomLine;
QWidget *keypadPage, *historyPage, *stackPage;
QComboBox* kpNumericCombo, *kpBaseCombo;
QRadioButton *kpDegreesButton, *kpRadiansButton, *kpGradiansButton, *kpNoAngleUnitButton;
QButtonGroup *kpAngleGroup;
QPushButton *kpExact, *kpFraction;
QalculateButton *kpSquare, *kpLog, *kpHyp, *kpSqrt, *kpCos, *kpRaise, *kpInv, *kpSin;
QalculateButton *kpTan, *kpLn, *kpFactorial, *kpMod, *kpAns, *kp8, *kp0, *kp7, *kpDel, *kpDot, *kp5, *kpEquals, *kpClear;
QalculateButton *kp3, *kp1, *kp4, *kp9, *kpDivision, *kpExp, *kp6, *kp2, *kpMinus, *kpTimes, *kpPlus;
QalculateHistoryBrowser *historyBrowser;
QPushButton *historyButton, *keypadButton, *stackButton;
KMenuBar *menubar;
QPopupMenu *menu_functions, *menu_variables, *menu_units, *menu_to_unit, *menu_set_prefix, *menu_modes;
KToggleAction *ActionAbbreviateNames, *ActionReadPrecision, *ActionNonZeroDenominators, *ActionWarnAboutDenominatorsAssumedNonZero;
KToggleAction *ActionLimitImplicitMultiplication, *ActionRPNMode, *ActionRPNSyntax, *ActionIndicateInfiniteSeries, *ActionNegativeExponents, *ActionSortMinusLast;
KToggleAction *ActionShowEndingZeroes, *ActionRoundHalfwayNumbersToEven, *ActionEnablePrefixes;
KToggleAction *ActionEnableUseOfAllPrefixes, *ActionEnableDenominatorPrefixes, *ActionPlaceUnitsSeparately;
KToggleAction *ActionEnableVariables, *ActionEnableFunctions, *ActionEnableUnits, *ActionEnableUnknowns;
KToggleAction *ActionCalculateVariables, *ActionAllowComplexResult, *ActionAllowInfiniteResult;
KRadioAction *ActionApproximationAlwaysExact, *ActionApproximationTryExact, *ActionApproximationApproximate;
KRadioAction *ActionAlgebraicModeSimplify, *ActionAlgebraicModeFactorize, *ActionAlgebraicModeNone;
KRadioAction *ActionFractionalDisplayDecimal, *ActionFractionalDisplayDecimalTryExact;
KRadioAction *ActionFractionalDisplayFraction, *ActionFractionalDisplayCombined;
KRadioAction *ActionNumericalDisplayEngineering, *ActionNumericalDisplayScientific, *ActionNumericalDisplayPurelyScientific, *ActionNumericalDisplaySimple, *ActionNumericalDisplayNormal;
KRadioAction *ActionNumberBaseBinary, *ActionNumberBaseOctal, *ActionNumberBaseDecimal, *ActionNumberBaseHexadecimal, *ActionNumberBaseOther;
KRadioAction *ActionNumberBaseSexagesimal, *ActionNumberBaseTimeFormat, *ActionNumberBaseRomanNumerals;
KRadioAction *ActionAssumptionTypeUnknown, *ActionAssumptionTypeNonMatrix, *ActionAssumptionTypeNumber, *ActionAssumptionTypeComplex, *ActionAssumptionTypeReal;
KRadioAction *ActionAssumptionTypeRational, *ActionAssumptionTypeInteger, *ActionAssumptionSignUnknown, *ActionAssumptionSignNonZero;
KRadioAction *ActionAssumptionSignPositive, *ActionAssumptionSignNonNegative, *ActionAssumptionSignNegative;
KRadioAction *ActionAssumptionSignNonPositive, *ActionAngleUnitDegrees, *ActionAngleUnitRadians, *ActionAngleUnitGradians;
KRadioAction *ActionAngleUnitNone, *ActionAutoNoConversion, *ActionAutoConvertToBaseUnits, *ActionAutoConvertToBestUnit;
KAction *ActionSetBase, *ActionPrecision, *ActionDecimals, *ActionSaveModeAs, *ActionDeleteMode, *ActionSaveMode, *ActionQuit;
KAction *ActionUpdateExchangeRates, *ActionManageVariables, *ActionConvertToUnitExpression, *ActionStoreResult, *ActionClose;
KAction *ActionConvertNumberBases, *ActionManageFunctions, *ActionConvertToBaseUnits, *ActionConvertToBestUnit;
KAction *ActionManageUnits, *ActionManageDataSets, *ActionFactorize, *ActionSimplify, *ActionSetUnknowns, *ActionCopyResult;
KAction *ActionPreferences, *ActionSaveAsImage, *ActionImportCSVFile, *ActionExportCSVFile, *ActionPeriodicTable;
KAction *ActionPlotFunctionsData, *ActionSaveDefinitions, *ActionNewVariable, *ActionNewMatrix, *ActionNewVector;
KAction *ActionNewUnknownVariable, *ActionNewFunction, *ActionNewUnit, *ActionNewDataSet;
KAction *ActionInsertMatrix, *ActionInsertVector;
KAction *ActionClearHistory;
KAction *ActionHideSystemTrayIcon, *ActionHide;
KAction *ActionClearStack, *ActionDeleteRegister, *ActionEditRegister;
KAction *ActionConfigureGlobalShortcuts;
KGlobalAccel *globalAccel;
QValueVector<int>::size_type current_history_index;
QValueVector<ModeObject*> mode_objects;
public slots:
void executeCommand2();
void setResult2();
void execute_expression2();
void showHide();
void configureGlobalShortcuts();
void update_fmenu();
void update_vmenu();
void update_umenus();
void insertVariable(Variable*);
void insertFunction(MathFunction*, QWidget *parent);
void applyFunction(MathFunction*, QWidget *parent);
void onExpressionChanged();
void onErrorTimeout();
bool fetch_exchange_rates(int);
void update_completion();
void insert_text(QString);
void aboutToQuit();
void onVariableMenuItemActivated(int);
void onFunctionMenuItemActivated(int);
void onUnitMenuItemActivated(int);
void onUnitsPrefixMenuItemActivated(int);
void precisionRecalculate();
void setMaxDecimals(int);
void setMinDecimals(int);
void execute();
void toggleHistory(bool);
void toggleStack(bool);
void toggleKeypad(bool);
void showEndingZeroes(bool);
void approximationTryExact();
void approximationAlwaysExact();
void approximationApproximate();
void fractionalDisplayDecimal();
void fractionalDisplayDecimalTryExact();
void fractionalDisplayFraction();
void fractionalDisplayCombined();
void numericalDisplayNormal();
void numericalDisplayEngineering();
void numericalDisplayScientific();
void numericalDisplayPurelyScientific();
void numericalDisplaySimple();
void indicateInfiniteSeries(bool);
void sortMinusLast(bool);
void negativeExponents(bool);
void roundHalfwayNumbersToEven(bool);
void abbreviateNames(bool);
void updateBaseOther();
void numberBaseBinary();
void numberBaseOctal();
void numberBaseDecimal();
void numberBaseOther();
void numberBaseHexadecimal();
void numberBaseSexagesimal();
void numberBaseTimeFormat();
void numberBaseRomanNumerals();
void setBaseInResultFromDialogGroup(int);
void setBaseInResultFromDialogBox(int);
void setBaseInExpressionFromDialogGroup(int);
void setBaseInExpressionFromDialogBox(int);
void setBase();
void nonZeroDenominators(bool);
void warnAboutDenominatorsAssumedNonZero(bool);
void algebraicModeSimplify();
void algebraicModeFactorize();
void algebraicModeNone();
void readPrecision(bool);
void limitImplicitMultiplication(bool);
void setPrecision(int);
void precision();
void decimals();
void rpnMode(bool);
void rpnSyntax(bool);
void assumptionSignUnknown();
void assumptionSignNonZero();
void assumptionSignPositive();
void assumptionSignNonNegative();
void assumptionSignNegative();
void assumptionSignNonPositive();
void assumptionTypeUnknown();
void assumptionTypeNonMatrix();
void assumptionTypeNumber();
void assumptionTypeComplex();
void assumptionTypeReal();
void assumptionTypeRational();
void assumptionTypeInteger();
void loadMode(int);
void onModesMenuItemActivated(int);
void saveModeAs();
void deleteMode();
void saveMode();
void angleUnitDegrees();
void angleUnitRadians();
void angleUnitGradians();
void angleUnitNone();
void autoNoConversion();
void autoConvertToBaseUnits();
void autoConvertToBestUnit();
void enablePrefixes(bool);
void enableUseOfAllPrefixes(bool);
void enableDenominatorPrefixes(bool);
void placeUnitsSeparately(bool);
void enableVariables(bool);
void enableFunctions(bool);
void enableUnits(bool);
void enableUnknowns(bool);
void calculateVariables(bool);
void allowComplexResult(bool);
void allowInfiniteResult(bool);
void updateExchangeRates();
void insertKP1();
void insertKP2();
void insertKP3();
void insertKP4();
void insertKP5();
void insertKP6();
void insertKP7();
void insertKP8();
void insertKP9();
void insertKP0();
void insertDot();
void insertExp();
void insertAns();
void insertMinus();
void insertPlus();
void insertTimes();
void insertDivision();
void insertCos();
void insertSin();
void insertTan();
void insertSqrt();
void insertLog();
void insertLn();
void insertRaise();
void clearExpression();
void expressionDel();
void insertSquare();
void setExactMode(bool);
void setFractionMode(bool);
void kpSetAngleUnit(int);
void kpSetBaseSelected(int);
void kpSetBase(int);
void kpSetNumericalMode(int);
void insertFactorial();
void insertMod();
void storeResult();
void manageVariables();
void convertToUnitConvertToDialogExpression();
void convertToUnitExpression();
void convertNumberBases();
void insertManagedFunction(MathFunction*);
void applyManagedFunction(MathFunction*);
void manageFunctions();
void manageUnits();
void insertUnit(Unit *u);
void convertResult(Unit *u);
void factorize();
void simplify();
void manageDataSets();
void setUnknownsApplyClicked();
void setUnknowns();
void convertToBaseUnits();
void convertToBestUnit();
void copyResult();
void clearHistory();
void preferences();
void applyPreferences();
void onConvertToUnitMenuItemActivated(int);
void onSetPrefixMenuItemActivated(int);
void periodicTable();
void plotFunctionsData();
void saveDefinitions();
void saveAsImage();
void importCSVFile();
void exportCSVFile();
void newVariable();
void newMatrix();
void newVector();
void newUnknownVariable();
void newFunction();
void newDataSet();
void newUnit();
void insertMatrix();
void insertVector();
void showSystemTrayIcon(bool);
void hideSystemTrayIcon();
void displayParseStatus();
void registerUp();
void registerDown();
void clearStack();
void deleteRegister();
void editRegister();
void updateRPNIndexes();
QListViewItem *getRPNRegister(size_t index);
void stackRegisterMoved();
void stackRegisterSet(QListViewItem*);
void popupStackMenu(KListView*, QListViewItem*, const QPoint&);
void registerSelected();
void editHistoryExpression();
void editHistoryParse();
void editHistoryResult();
void insertHistoryResultVariable();
protected:
void updateButtonWidths();
void applySetUnknowns(bool okclicked);
bool b_unknowns_changed;
QValueVector<bool> unknown_changed;
MathStructure *mstruct_before_unknowns, *unknowns_mstruct;
QValueVector<KLineEdit*> unknowns_entries;
bool queryClose();
QString parsed_expression;
void keyPressEvent(QKeyEvent *e);
void fontChange(const QFont &old_font);
void saveProperties(KConfig *cfg);
void readProperties(KConfig *cfg);
private:
bool close_to_systray_was;
bool display_expression_status_was;
int history_height;
};
class QalculateHistoryBrowser : public KTextBrowser {
Q_OBJECT
public:
QalculateHistoryBrowser(QWidget *parent, const char *name);
~QalculateHistoryBrowser();
protected:
QPopupMenu *createPopupMenu(const QPoint &pos);
};
class QalculateParseLabel : public QLabel {
Q_OBJECT
public:
QalculateParseLabel(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateParseLabel();
void setText(QString text, bool break_begin, bool error_color, bool warning_color);
protected:
QString parsetext;
bool bb, ec, wc;
void drawContents(QPainter *p);
};
class QalculateButton : public QPushButton {
Q_OBJECT
public:
QalculateButton(QWidget *parent = 0, const char *name = 0);
QalculateButton(const QString &text, QWidget *parent = 0, const char *name = 0);
QalculateButton(const QIconSet &icon, const QString &text, QWidget *parent = 0, const char *name = 0);
virtual ~QalculateButton();
void setUseMinThreeCharWidth(bool b);
void setMarkup(const QString &str);
QSize sizeHint() const;
private:
bool umtcw;
};
class QalculateStyleSheet : public QStyleSheet {
Q_OBJECT
public:
QalculateStyleSheet(QObject *parent = 0, const char *name = 0);
virtual ~QalculateStyleSheet();
void scaleFont(QFont &font, int logicalSize) const;
};
class QalculateRPNStackListView : public KListView {
Q_OBJECT
public:
QalculateRPNStackListView(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateRPNStackListView();
protected:
void keyPressEvent(QKeyEvent *e);
};
class QalculateModeDialog : public KDialogBase {
Q_OBJECT
protected:
KKeyButton *keyButton;
KComboBox *modeCombo;
public:
QalculateModeDialog(QWidget *parent);
virtual ~QalculateModeDialog();
QString modeName();
const KShortcut &modeShortcut();
public slots:
void slotOk();
void updateShortcut(const KShortcut&);
void modeSelected(int);
};
#endif // QALCULATE_KWINDOW_H

@ -0,0 +1,306 @@
/***************************************************************************
* Copyright (C) 2005-2006 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "kqalculate.h"
#include "preferences.h"
#include <kwin.h>
#include <kuniqueapplication.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <klocale.h>
#include <unistd.h>
#include <qtextcodec.h>
#include <qobject.h>
#include <kmessagebox.h>
#include <qtimer.h>
#include <klineedit.h>
#include <qtooltip.h>
#include <qclipboard.h>
#include "qalculateexpressionedit.h"
#include "qalculateresultdisplay.h"
#include "qalculate_kde_utils.h"
static const char description[] = I18N_NOOP("A powerful and easy to use desktop calculator");
static const char version[] = VERSION;
static KCmdLineOptions options[] = {
{"c", 0, 0},
{"clipboard", I18N_NOOP("Calculate X11-clipboard content (selected text)"), 0},
{"+[Expression]", I18N_NOOP( "Initial expression to calculate" ), 0},
KCmdLineLastOption
};
extern KnownVariable *vans[5];
extern MathStructure *mstruct, *matrix_mstruct, *parsed_mstruct, *parsed_tostruct;
extern QString result_text, result_history_text, parsed_text;
extern QWidget *expressionWidget, *resultWidget, *statusWidget_l;
extern QWidget *topWidget;
extern KQalculate *mainWin;
extern bool load_global_defs, fetch_exchange_rates_at_startup, first_time, first_qalculate_run;
extern bool b_busy;
extern bool canplot;
extern bool close_to_systray;
extern FILE *view_pipe_r, *view_pipe_w, *command_pipe_r, *command_pipe_w;
extern pthread_t view_thread, command_thread;
extern pthread_attr_t view_thread_attr, command_thread_attr;
extern bool command_thread_started;
extern QValueVector<QString> recent_functions_pre;
extern QValueVector<QString> recent_variables_pre;
extern QValueVector<QString> recent_units_pre;
QTimer *error_timer;
void create_qalculate_window(KUniqueApplication *parent) {
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf8"));
b_busy = false;
new Calculator();
if(KGlobal::locale()->decimalSymbol() == ",") CALCULATOR->useDecimalComma();
CALCULATOR->place_currency_code_before = KGlobal::locale()->positivePrefixCurrencySymbol();
//load application specific preferences
load_preferences();
mstruct = new MathStructure();
parsed_mstruct = new MathStructure();
parsed_tostruct = new MathStructure();
parsed_tostruct->setUndefined();
matrix_mstruct = new MathStructure();
canplot = CALCULATOR->canPlot();
mainWin = new KQalculate(parent);
topWidget = mainWin;
expressionWidget = (QWidget*) mainWin->expressionEdit;
resultWidget = (QWidget*) mainWin->resultLabel;
statusWidget_l = (QWidget*) mainWin->statusLabel_l;
}
QString parse_expression_arguments(KCmdLineArgs *args) {
QString calc_arg;
if(args->isSet("clipboard")) {
calc_arg = qApp->clipboard()->text(QClipboard::Selection);
if(calc_arg.isEmpty()) {
calc_arg = qApp->clipboard()->text(QClipboard::Clipboard);
}
} else {
for(int i = 0; i < args->count(); i++) {
if(i > 0) {
calc_arg += " ";
}
calc_arg += args->arg(i);
}
}
return calc_arg;
}
void start_qalculate() {
KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
QString calc_arg = parse_expression_arguments(args);
args->clear();
if(!calc_arg.isEmpty()) {
mainWin->expressionEdit->setText(calc_arg);
} else if(first_time) {
mainWin->resultLabel->setText(i18n("Enter a mathematical expression above.<br>Ex. 5 + 2 / 3"));
} else {
mainWin->resultLabel->setText("<div align=\"right\"><font size=2>&nbsp;<br></font><font size=6>= 0</font></div>");
}
qApp->processEvents();
//exchange rates
if(first_qalculate_run) {
if(KMessageBox::questionYesNo(mainWin, i18n("You need to download exchange rates to be able to convert between different currencies. You can later get current exchange rates by selecting \"Update Exchange Rates\" under the File menu.\n\nDo you want to fetch exchange rates now from the Internet?"), i18n("Update exchange rates?")) == KMessageBox::Yes) {
qApp->processEvents();
mainWin->fetch_exchange_rates(5);
}
qApp->processEvents();
} else if(fetch_exchange_rates_at_startup) {
mainWin->fetch_exchange_rates(5);
qApp->processEvents();
}
CALCULATOR->loadExchangeRates();
string ans_str = i18n("ans").ascii();
vans[0] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str, m_undefined, i18n("Last Answer").ascii(), false));
vans[0]->addName(i18n("answer").ascii());
vans[0]->addName(ans_str + "1");
vans[1] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "2", m_undefined, i18n("Answer 2").ascii(), false));
vans[2] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "3", m_undefined, i18n("Answer 3").ascii(), false));
vans[3] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "4", m_undefined, i18n("Answer 4").ascii(), false));
vans[4] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "5", m_undefined, i18n("Answer 5").ascii(), false));
//load global definitions
if(load_global_defs && !CALCULATOR->loadGlobalDefinitions()) {
KMessageBox::error(mainWin, i18n("Failed to load global definitions!"), i18n("Error"));
qApp->processEvents();
}
//load local definitions
CALCULATOR->loadLocalDefinitions();
//check for calculation errros regularly
error_timer = new QTimer(mainWin);
QObject::connect(error_timer, SIGNAL(timeout()), mainWin, SLOT(onErrorTimeout()));
generate_units_tree_struct();
generate_functions_tree_struct();
generate_variables_tree_struct();
mainWin->create_fmenu();
mainWin->create_vmenu();
mainWin->create_umenu();
mainWin->create_toumenu();
mainWin->create_setpmenu();
for(int i = ((int) recent_functions_pre.size()) - 1; i >= 0; i--) {
mainWin->function_inserted(CALCULATOR->getActiveFunction(recent_functions_pre[i].ascii()));
}
for(int i = ((int) recent_variables_pre.size()) - 1; i >= 0; i--) {
mainWin->variable_inserted(CALCULATOR->getActiveVariable(recent_variables_pre[i].ascii()));
}
for(int i = ((int) recent_units_pre.size()) - 1; i >= 0; i--) {
Unit *u = CALCULATOR->getActiveUnit(recent_units_pre[i].ascii());
if(!u) u = CALCULATOR->getCompositeUnit(recent_units_pre[i].ascii());
mainWin->unit_inserted(u);
}
mainWin->update_completion();
int pipe_wr[] = {0, 0};
pipe(pipe_wr);
view_pipe_r = fdopen(pipe_wr[0], "r");
view_pipe_w = fdopen(pipe_wr[1], "w");
pthread_attr_init(&view_thread_attr);
pthread_create(&view_thread, &view_thread_attr, view_proc, view_pipe_r);
int pipe_wr2[] = {0, 0};
pipe(pipe_wr2);
command_pipe_r = fdopen(pipe_wr2[0], "r");
command_pipe_w = fdopen(pipe_wr2[1], "w");
pthread_attr_init(&command_thread_attr);
command_thread_started = false;
QObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()));
QObject::connect(qApp, SIGNAL(aboutToQuit()), mainWin, SLOT(aboutToQuit()));
error_timer->start(100);
if(!calc_arg.isEmpty()) {
mainWin->execute_expression();
}
}
class QalculateApp : public KUniqueApplication {
public:
bool started;
QalculateApp() {started = false;}
virtual ~QalculateApp() {}
int newInstance() {
if(mainWin && started) {
KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
QString calc_arg = parse_expression_arguments(args);
args->clear();
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
KWin::Info info = KWin::info(mainWin->winId());
KWin::setOnDesktop(mainWin->winId(), KWin::currentDesktop());
mainWin->move(info.geometry.topLeft());
#else
KWin::WindowInfo info = KWin::windowInfo(mainWin->winId(), (unsigned long) NET::WMGeometry);
KWin::setOnDesktop(mainWin->winId(), KWin::currentDesktop());
mainWin->move(info.geometry().topLeft());
#endif
mainWin->setShown(true);
mainWin->show();
mainWin->raise();
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
KWin::setActiveWindow(mainWin->winId());
#else
KWin::activateWindow(mainWin->winId());
#endif
if(!calc_arg.isEmpty()) {
mainWin->expressionEdit->setText(calc_arg);
mainWin->execute_expression();
}
return 0;
} else {
if(isRestored() && KMainWindow::canBeRestored(1)) {
create_qalculate_window(this);
setMainWidget(mainWin);
mainWin->restore(1, false);
start_qalculate();
} else {
create_qalculate_window(this);
setMainWidget(mainWin);
mainWin->show();
start_qalculate();
}
started = true;
return KUniqueApplication::newInstance();
}
started = true;
return 0;
}
};
int main(int argc, char **argv) {
mainWin = NULL;
KAboutData about(PACKAGE, I18N_NOOP("Qalculate!"), version, description, KAboutData::License_GPL, "(C) 2005-2006 Niklas Knutsson", 0, "http://qalculate.sourceforge.net/", "nique769@users.sourceforge.net");
about.addAuthor("Niklas Knutsson", 0, "nq@altern.org");
KCmdLineArgs::init(argc, argv, &about);
KCmdLineArgs::addCmdLineOptions(options);
KUniqueApplication::addCmdLineOptions();
if(!QalculateApp::start()) {
return 0;
}
QalculateApp app;
return app.exec();
}

@ -0,0 +1,865 @@
/***************************************************************************
* Copyright (C) 2005-2007 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "preferences.h"
#include "kqalculate.h"
#include "qalculate_kde_utils.h"
#include "qalculateexpressionedit.h"
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
#include <stdio.h>
#include <klocale.h>
#include <qstringlist.h>
#include <ktextbrowser.h>
#include <qwidgetstack.h>
#include <qpushbutton.h>
#include <qvaluevector.h>
PrintOptions printops;
EvaluationOptions evalops;
bool rpn_mode;
bool rpn_keypad_only;
bool load_global_defs, fetch_exchange_rates_at_startup, first_time, first_qalculate_run, save_mode_on_exit, save_defs_on_exit;
bool use_custom_result_font, use_custom_expression_font, use_custom_status_font;
int use_icon_buttons;
QString custom_result_font, custom_expression_font, custom_status_font;
QColor status_warning_color, status_error_color;
bool display_expression_status;
bool close_to_systray;
bool enable_expression_completion;
PlotLegendPlacement default_plot_legend_placement;
bool default_plot_display_grid;
bool default_plot_full_border;
QString default_plot_min;
QString default_plot_max;
QString default_plot_step;
int default_plot_sampling_rate;
bool default_plot_use_sampling_rate;
bool default_plot_rows;
int default_plot_type;
PlotStyle default_plot_style;
PlotSmoothing default_plot_smoothing;
QString default_plot_variable;
bool default_plot_color;
bool enable_plot_expression_completion;
bool canplot;
QString initial_history;
extern vector<MathFunction*> recent_functions;
extern vector<Variable*> recent_variables;
extern vector<Unit*> recent_units;
QValueVector<QString> recent_functions_pre;
QValueVector<QString> recent_variables_pre;
QValueVector<QString> recent_units_pre;
extern QWidget *expressionWidget;
extern KQalculate *mainWin;
QStringList expression_history;
bool show_keypad, show_history, show_stack;
vector<mode_struct> modes;
QValueVector<QString> inhistory;
QValueVector<int> inhistory_type;
QValueVector<int> inhistory_id;
int inhistory_current_id;
/*
save mode to file
*/
void save_mode() {
return save_preferences(true);
}
/*
remember current mode
*/
void set_saved_mode() {
modes[1].precision = CALCULATOR->getPrecision();
modes[1].po = printops;
modes[1].po.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
modes[1].eo = evalops;
modes[1].at = CALCULATOR->defaultAssumptions()->type();
modes[1].as = CALCULATOR->defaultAssumptions()->sign();
modes[1].rpn_mode = rpn_mode;
}
size_t save_mode_as(QString name, bool *new_mode) {
name = name.stripWhiteSpace();
size_t index = 0;
for(; index < modes.size(); index++) {
if(modes[index].name == name) {
if(new_mode) *new_mode = false;
break;
}
}
if(index >= modes.size()) {
modes.resize(modes.size() + 1);
index = modes.size() - 1;
if(new_mode) *new_mode = true;
}
modes[index].po = printops;
modes[index].po.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
modes[index].eo = evalops;
modes[index].precision = CALCULATOR->getPrecision();
modes[index].at = CALCULATOR->defaultAssumptions()->type();
modes[index].as = CALCULATOR->defaultAssumptions()->sign();
modes[index].name = name;
modes[index].rpn_mode = rpn_mode;
return index;
}
void load_preferences() {
default_plot_legend_placement = PLOT_LEGEND_TOP_RIGHT;
default_plot_display_grid = true;
default_plot_full_border = false;
default_plot_min = "0";
default_plot_max = "10";
default_plot_step = "1";
default_plot_sampling_rate = 100;
default_plot_rows = false;
default_plot_type = 0;
default_plot_style = PLOT_STYLE_LINES;
default_plot_smoothing = PLOT_SMOOTHING_NONE;
default_plot_variable = "x";
default_plot_color = true;
default_plot_use_sampling_rate = true;
printops.is_approximate = new bool(false);
printops.prefix = NULL;
printops.use_min_decimals = false;
printops.use_denominator_prefix = true;
printops.min_decimals = 0;
printops.use_max_decimals = false;
printops.max_decimals = 2;
printops.base = 10;
printops.min_exp = EXP_PRECISION;
printops.negative_exponents = false;
printops.sort_options.minus_last = true;
printops.indicate_infinite_series = false;
printops.show_ending_zeroes = false;
printops.round_halfway_to_even = false;
printops.number_fraction_format = FRACTION_DECIMAL;
printops.abbreviate_names = true;
printops.use_unicode_signs = true;
printops.use_unit_prefixes = true;
printops.spacious = true;
printops.short_multiplication = true;
printops.limit_implicit_multiplication = false;
printops.place_units_separately = true;
printops.use_all_prefixes = false;
printops.excessive_parenthesis = false;
printops.allow_non_usable = false;
printops.lower_case_numbers = false;
printops.lower_case_e = false;
printops.base_display = BASE_DISPLAY_NORMAL;
printops.division_sign = DIVISION_SIGN_DIVISION_SLASH;
printops.multiplication_sign = MULTIPLICATION_SIGN_DOT;
printops.can_display_unicode_string_function = &can_display_unicode_string_function;
printops.allow_factorization = false;
printops.spell_out_logical_operators = true;
evalops.parse_options.limit_implicit_multiplication = false;
evalops.approximation = APPROXIMATION_TRY_EXACT;
evalops.sync_units = true;
evalops.structuring = STRUCTURING_SIMPLIFY;
evalops.parse_options.unknowns_enabled = false;
evalops.parse_options.read_precision = DONT_READ_PRECISION;
evalops.parse_options.base = BASE_DECIMAL;
evalops.allow_complex = true;
evalops.allow_infinite = true;
evalops.auto_post_conversion = POST_CONVERSION_NONE;
evalops.assume_denominators_nonzero = true;
evalops.warn_about_denominators_assumed_nonzero = true;
evalops.parse_options.angle_unit = ANGLE_UNIT_RADIANS;
evalops.parse_options.dot_as_separator = KGlobal::locale()->thousandsSeparator() == ".";
rpn_mode = false;
rpn_keypad_only = true;
save_mode_as(i18n("Preset"));
save_mode_as(i18n("Default"));
size_t mode_index = 1;
inhistory_current_id = 0;
status_warning_color.setNamedColor("blue");
status_error_color.setNamedColor("red");
use_icon_buttons = 1;
enable_expression_completion = true;
enable_plot_expression_completion = true;
close_to_systray = false;
show_keypad = true;
show_history = false;
show_stack = true;
display_expression_status = true;
save_mode_on_exit = true;
save_defs_on_exit = true;
use_custom_result_font = false;
use_custom_expression_font = false;
use_custom_status_font = false;
custom_result_font = "";
custom_expression_font = "";
custom_status_font = "";
load_global_defs = true;
fetch_exchange_rates_at_startup = false;
first_time = false;
string filename = getLocalDir();
DIR *dir = opendir(filename.c_str());
if(!dir) {
first_qalculate_run = true;
first_time = true;
set_saved_mode();
return;
} else {
first_qalculate_run = false;
closedir(dir);
}
int version_numbers[] = {0, 9, 6};
FILE *file = NULL;
filename += "qalculate-kde.cfg";
file = fopen(filename.c_str(), "r");
if(file) {
char line[10000];
QString stmp, svalue, svar;
int i;
int v;
while(true) {
if(fgets(line, 10000, file) == NULL)
break;
stmp = line;
stmp = stmp.stripWhiteSpace();
if((i = stmp.find("=")) >= 0) {
svar = stmp;
svar.truncate(i);
svar = svar.stripWhiteSpace();
svalue = stmp;
svalue.remove(0, i + 1);
svalue = svalue.stripWhiteSpace();
v = svalue.toInt();
if(svar == "version") {
parse_qalculate_version(svalue.ascii(), version_numbers);
} else if(svar == "shortcut") {
if(mode_index != 1) modes[mode_index].shortcut.init(svalue);
} else if(svar == "save_mode_on_exit") {
save_mode_on_exit = v;
} else if(svar == "save_definitions_on_exit") {
save_defs_on_exit = v;
} else if(svar == "fetch_exchange_rates_at_startup") {
fetch_exchange_rates_at_startup = v;
} else if(svar == "min_deci") {
if(mode_index == 1) printops.min_decimals = v;
else modes[mode_index].po.min_decimals = v;
} else if(svar == "use_min_deci") {
if(mode_index == 1) printops.use_min_decimals = v;
else modes[mode_index].po.use_min_decimals = v;
} else if(svar == "max_deci") {
if(mode_index == 1) printops.max_decimals = v;
else modes[mode_index].po.max_decimals = v;
} else if(svar == "use_max_deci") {
if(mode_index == 1) printops.use_max_decimals = v;
else modes[mode_index].po.use_max_decimals = v;
} else if(svar == "precision") {
if(mode_index == 1) CALCULATOR->setPrecision(v);
else modes[mode_index].precision = v;
} else if(svar == "min_exp") {
if(mode_index == 1) printops.min_exp = v;
else modes[mode_index].po.min_exp = v;
} else if(svar == "negative_exponents") {
if(mode_index == 1) printops.negative_exponents = v;
else modes[mode_index].po.negative_exponents = v;
} else if(svar == "sort_minus_last") {
if(mode_index == 1) printops.sort_options.minus_last = v;
else modes[mode_index].po.sort_options.minus_last = v;
} else if(svar == "place_units_separately") {
if(mode_index == 1) printops.place_units_separately = v;
else modes[mode_index].po.place_units_separately = v;
} else if(svar == "use_prefixes") {
if(mode_index == 1) printops.use_unit_prefixes = v;
else modes[mode_index].po.use_unit_prefixes = v;
} else if(svar == "number_fraction_format") {
if(v >= FRACTION_DECIMAL && v <= FRACTION_COMBINED) {
if(mode_index == 1) printops.number_fraction_format = (NumberFractionFormat) v;
else modes[mode_index].po.number_fraction_format = (NumberFractionFormat) v;
}
} else if(svar == "number_base") {
if(mode_index == 1) printops.base = v;
else modes[mode_index].po.base = v;
} else if(svar == "number_base_expression") {
if(mode_index == 1) evalops.parse_options.base = v;
else modes[mode_index].eo.parse_options.base = v;
} else if(svar == "read_precision") {
if(v >= DONT_READ_PRECISION && v <= READ_PRECISION_WHEN_DECIMALS) {
if(mode_index == 1) evalops.parse_options.read_precision = (ReadPrecisionMode) v;
else modes[mode_index].eo.parse_options.read_precision = (ReadPrecisionMode) v;
}
} else if(svar == "assume_denominators_nonzero") {
if(version_numbers[0] == 0 && (version_numbers[1] < 9 || (version_numbers[1] == 9 && version_numbers[2] == 0))) {
v = true;
}
if(mode_index == 1) evalops.assume_denominators_nonzero = v;
else modes[mode_index].eo.assume_denominators_nonzero = v;
} else if(svar == "warn_about_denominators_assumed_nonzero") {
if(mode_index == 1) evalops.warn_about_denominators_assumed_nonzero = v;
else modes[mode_index].eo.warn_about_denominators_assumed_nonzero = v;
} else if(svar == "structuring") {
if(v >= STRUCTURING_NONE && v <= STRUCTURING_FACTORIZE) {
if(mode_index == 1) {
evalops.structuring = (StructuringMode) v;
printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE);
} else {
modes[mode_index].eo.structuring = (StructuringMode) v;
modes[mode_index].po.allow_factorization = (modes[mode_index].eo.structuring == STRUCTURING_FACTORIZE);
}
}
} else if(svar == "angle_unit") {
if(v >= ANGLE_UNIT_NONE && v <= ANGLE_UNIT_GRADIANS) {
if(mode_index == 1) evalops.parse_options.angle_unit = (AngleUnit) v;
else modes[mode_index].eo.parse_options.angle_unit = (AngleUnit) v;
}
} else if(svar == "functions_enabled") {
if(mode_index == 1) evalops.parse_options.functions_enabled = v;
else modes[mode_index].eo.parse_options.functions_enabled = v;
} else if(svar == "variables_enabled") {
if(mode_index == 1) evalops.parse_options.variables_enabled = v;
else modes[mode_index].eo.parse_options.variables_enabled = v;
} else if(svar == "calculate_variables") {
if(mode_index == 1) evalops.calculate_variables = v;
else modes[mode_index].eo.calculate_variables = v;
} else if(svar == "calculate_functions") {
if(mode_index == 1) evalops.calculate_functions = v;
else modes[mode_index].eo.calculate_functions = v;
} else if(svar == "sync_units") {
if(mode_index == 1) evalops.sync_units = v;
else modes[mode_index].eo.sync_units = v;
} else if(svar == "unknownvariables_enabled") {
if(mode_index == 1) evalops.parse_options.unknowns_enabled = v;
else modes[mode_index].eo.parse_options.unknowns_enabled = v;
} else if(svar == "units_enabled") {
if(mode_index == 1) evalops.parse_options.units_enabled = v;
else modes[mode_index].eo.parse_options.units_enabled = v;
} else if(svar == "allow_complex") {
if(mode_index == 1) evalops.allow_complex = v;
else modes[mode_index].eo.allow_complex = v;
} else if(svar == "allow_infinite") {
if(mode_index == 1) evalops.allow_infinite = v;
else modes[mode_index].eo.allow_infinite = v;
} else if(svar == "use_short_units") {
if(mode_index == 1) printops.abbreviate_names = v;
else modes[mode_index].po.abbreviate_names = v;
} else if(svar == "abbreviate_names") {
if(mode_index == 1) printops.abbreviate_names = v;
else modes[mode_index].po.abbreviate_names = v;
} else if(svar == "all_prefixes_enabled") {
if(mode_index == 1) printops.use_all_prefixes = v;
else modes[mode_index].po.use_all_prefixes = v;
} else if(svar == "denominator_prefix_enabled") {
if(mode_index == 1) printops.use_denominator_prefix = v;
else modes[mode_index].po.use_denominator_prefix = v;
} else if(svar == "auto_post_conversion") {
if(v >= POST_CONVERSION_NONE && v <= POST_CONVERSION_BASE) {
if(mode_index == 1) evalops.auto_post_conversion = (AutoPostConversion) v;
else modes[mode_index].eo.auto_post_conversion = (AutoPostConversion) v;
}
} else if(svar == "indicate_infinite_series") {
if(mode_index == 1) printops.indicate_infinite_series = v;
else modes[mode_index].po.indicate_infinite_series = v;
} else if(svar == "show_ending_zeroes") {
if(mode_index == 1) printops.show_ending_zeroes = v;
else modes[mode_index].po.show_ending_zeroes = v;
} else if(svar == "round_halfway_to_even") {
if(mode_index == 1) printops.round_halfway_to_even = v;
else modes[mode_index].po.round_halfway_to_even = v;
} else if(svar == "approximation") {
if(v >= APPROXIMATION_EXACT && v <= APPROXIMATION_APPROXIMATE) {
if(mode_index == 1) evalops.approximation = (ApproximationMode) v;
else modes[mode_index].eo.approximation = (ApproximationMode) v;
}
} else if(svar == "in_rpn_mode") {
if(mode_index == 1) rpn_mode = v;
else modes[mode_index].rpn_mode = v;
} else if(svar == "rpn_keypad_only") {
rpn_keypad_only = v;
} else if(svar == "rpn_syntax") {
if(mode_index == 1) evalops.parse_options.rpn = v;
else modes[mode_index].eo.parse_options.rpn = v;
} else if(svar == "limit_implicit_multiplication") {
if(mode_index == 1) {
evalops.parse_options.limit_implicit_multiplication = v;
printops.limit_implicit_multiplication = v;
} else {
modes[mode_index].eo.parse_options.limit_implicit_multiplication = v;
modes[mode_index].po.limit_implicit_multiplication = v;
}
} else if(svar == "default_assumption_type") {
if(v >= ASSUMPTION_TYPE_NONE && v <= ASSUMPTION_TYPE_INTEGER) {
if(v == ASSUMPTION_TYPE_NONE && version_numbers[0] == 0 && (version_numbers[1] < 9 || (version_numbers[1] == 9 && version_numbers[2] == 0))) {
v = ASSUMPTION_TYPE_NONMATRIX;
}
if(mode_index == 1) CALCULATOR->defaultAssumptions()->setType((AssumptionType) v);
else modes[mode_index].at = (AssumptionType) v;
}
} else if(svar == "default_assumption_sign") {
if(v >= ASSUMPTION_SIGN_UNKNOWN && v <= ASSUMPTION_SIGN_NONZERO) {
if(v == ASSUMPTION_SIGN_NONZERO && version_numbers[0] == 0 && (version_numbers[1] < 9 || (version_numbers[1] == 9 && version_numbers[2] == 0))) {
v = ASSUMPTION_SIGN_UNKNOWN;
}
if(mode_index == 1) CALCULATOR->defaultAssumptions()->setSign((AssumptionSign) v);
else modes[mode_index].as = (AssumptionSign) v;
}
} else if(svar == "spacious") {
if(mode_index == 1) printops.spacious = v;
else modes[mode_index].po.spacious = v;
} else if(svar == "excessive_parenthesis") {
if(mode_index == 1) printops.excessive_parenthesis = v;
else modes[mode_index].po.excessive_parenthesis = v;
} else if(svar == "short_multiplication") {
if(mode_index == 1) printops.short_multiplication = v;
else modes[mode_index].po.short_multiplication = v;
} else if(svar == "use_unicode_signs") {
printops.use_unicode_signs = v;
} else if(svar == "lower_case_numbers") {
printops.lower_case_numbers = v;
} else if(svar == "lower_case_e") {
printops.lower_case_e = v;
} else if(svar == "base_display") {
if(v >= BASE_DISPLAY_NONE && v <= BASE_DISPLAY_ALTERNATIVE) printops.base_display = (BaseDisplay) v;
} else if(svar == "spell_out_logical_operators") {
printops.spell_out_logical_operators = v;
} else if(svar == "dot_as_separator") {
evalops.parse_options.dot_as_separator = v;
} else if(svar == "use_custom_result_font") {
use_custom_result_font = v;
} else if(svar == "use_custom_expression_font") {
use_custom_expression_font = v;
} else if(svar == "use_custom_status_font") {
use_custom_status_font = v;
} else if(svar == "custom_result_font") {
custom_result_font = svalue;
} else if(svar == "custom_expression_font") {
custom_expression_font = svalue;
} else if(svar == "custom_status_font") {
custom_status_font = svalue;
} else if(svar == "status_error_color") {
status_error_color.setNamedColor(svalue);
} else if(svar == "status_warning_color") {
status_warning_color.setNamedColor(svalue);
} else if(svar == "multiplication_sign") {
if(v >= MULTIPLICATION_SIGN_ASTERISK && v <= MULTIPLICATION_SIGN_X) printops.multiplication_sign = (MultiplicationSign) v;
} else if(svar == "division_sign") {
if(v >= DIVISION_SIGN_SLASH && v <= DIVISION_SIGN_DIVISION) printops.division_sign = (DivisionSign) v;
} else if(svar == "close_to_system_tray") {
close_to_systray = v;
} else if(svar == "show_keypad") {
show_keypad = v;
} else if(svar == "show_history") {
show_history = v;
} else if(svar == "show_stack") {
show_stack = v;
} else if(svar == "display_expression_status") {
display_expression_status = v;
} else if(svar == "enable_expression_completion") {
enable_expression_completion = v;
} else if(svar == "use_icon_buttons") {
use_icon_buttons = v;
} else if(svar == "plot_legend_placement") {
if(v >= PLOT_LEGEND_NONE && v <= PLOT_LEGEND_OUTSIDE) default_plot_legend_placement = (PlotLegendPlacement) v;
} else if(svar == "plot_style") {
if(v >= PLOT_STYLE_LINES && v <= PLOT_STYLE_DOTS) default_plot_style = (PlotStyle) v;
} else if(svar == "plot_smoothing") {
if(v >= PLOT_SMOOTHING_NONE && v <= PLOT_SMOOTHING_SBEZIER) default_plot_smoothing = (PlotSmoothing) v;
} else if(svar == "plot_display_grid") {
default_plot_display_grid = v;
} else if(svar == "plot_full_border") {
default_plot_full_border = v;
} else if(svar == "plot_min") {
default_plot_min = svalue;
} else if(svar == "plot_max") {
default_plot_max = svalue;
} else if(svar == "plot_step") {
default_plot_step = svalue;
} else if(svar == "plot_sampling_rate") {
default_plot_sampling_rate = v;
} else if(svar == "plot_use_sampling_rate") {
default_plot_use_sampling_rate = v;
} else if(svar == "plot_variable") {
default_plot_variable = svalue;
} else if(svar == "plot_rows") {
default_plot_rows = v;
} else if(svar == "plot_type") {
default_plot_type = v;
} else if(svar == "plot_color") {
default_plot_color = v;
} else if(svar == "enable_plot_expression_completion") {
enable_plot_expression_completion = v;
} else if(svar == "expression_history") {
expression_history.push_back(svalue);
} else if(svar == "history") {
initial_history = svalue;
if(version_numbers[1] < 9) {
initial_history.replace("<br><br>", "<br><hr>");
}
inhistory.push_back(initial_history);
inhistory_type.push_back(QALCULATE_HISTORY_OLD);
} else if(svar == "history_old") {
inhistory.push_back(svalue);
inhistory_type.push_back(QALCULATE_HISTORY_OLD);
} else if(svar == "history_expression") {
inhistory.push_back(svalue);
inhistory_type.push_back(QALCULATE_HISTORY_EXPRESSION);
} else if(svar == "history_transformation") {
inhistory.push_back(svalue);
inhistory_type.push_back(QALCULATE_HISTORY_TRANSFORMATION);
} else if(svar == "history_result") {
inhistory.push_back(svalue);
inhistory_type.push_back(QALCULATE_HISTORY_RESULT);
} else if(svar == "history_result_approximate") {
inhistory.push_back(svalue);
inhistory_type.push_back(QALCULATE_HISTORY_RESULT_APPROXIMATE);
} else if(svar == "history_parse") {
inhistory.push_back(svalue);
inhistory_type.push_back(QALCULATE_HISTORY_PARSE);
} else if(svar == "history_parse_approximate") {
inhistory.push_back(svalue);
inhistory_type.push_back(QALCULATE_HISTORY_PARSE_APPROXIMATE);
} else if(svar == "history_register_moved") {
inhistory.push_back(svalue);
inhistory_type.push_back(QALCULATE_HISTORY_REGISTER_MOVED);
} else if(svar == "history_warning") {
inhistory.push_back(svalue);
inhistory_type.push_back(QALCULATE_HISTORY_WARNING);
} else if(svar == "history_error") {
inhistory.push_back(svalue);
inhistory_type.push_back(QALCULATE_HISTORY_ERROR);
} else if(svar == "history_continued") {
if(inhistory.size() > 0) {
inhistory[inhistory.size() - 1] += "<br>";
inhistory[inhistory.size() - 1] += svalue;
}
} else if(svar == "recent_functions") {
int v_i = 0;
while(true) {
v_i = svalue.find(',');
if(v_i < 0) {
svar = svalue.stripWhiteSpace();
if(!svar.isEmpty()) {
recent_functions_pre.push_back(svar);
}
break;
} else {
svar = svalue;
svar.truncate(v_i);
svalue.remove(0, v_i + 1);
svar = svar.stripWhiteSpace();
if(!svar.isEmpty()) {
recent_functions_pre.push_back(svar);
}
}
}
} else if(svar == "recent_variables") {
int v_i = 0;
while(true) {
v_i = svalue.find(',');
if(v_i < 0) {
svar = svalue.stripWhiteSpace();
if(!svar.isEmpty()) {
recent_variables_pre.push_back(svar);
}
break;
} else {
svar = svalue;
svar.truncate(v_i);
svalue.remove(0, v_i + 1);
svar = svar.stripWhiteSpace();
if(!svar.isEmpty()) {
recent_variables_pre.push_back(svar);
}
}
}
} else if(svar == "recent_units") {
int v_i = 0;
while(true) {
v_i = svalue.find(',');
if(v_i < 0) {
svar = svalue.stripWhiteSpace();
if(!svar.isEmpty()) {
recent_units_pre.push_back(svar);
}
break;
} else {
svar = svalue;
svar.truncate(v_i);
svalue.remove(0, v_i + 1);
svar = svar.stripWhiteSpace();
if(!svar.isEmpty()) {
recent_units_pre.push_back(svar);
}
}
}
}
} else if(stmp.length() > 2 && stmp[0] == '[' && stmp[stmp.length() - 1] == ']') {
stmp.truncate(stmp.length() - 1);
stmp.remove(0, 1);
stmp = stmp.stripWhiteSpace();
if(stmp == "Mode") {
mode_index = 1;
} else if(stmp.length() > 5) {
QString svar = stmp;
svar.truncate(4);
if(svar == "Mode") {
stmp.remove(0, 5);
mode_index = save_mode_as(stmp);
}
}
}
}
inhistory_current_id = (int) inhistory.size();
int id = inhistory_current_id;
id--;
for(QValueVector<QString>::size_type i = 0; i < inhistory.size(); i++) {
inhistory_id.push_back(id);
id--;
}
} else {
first_time = true;
}
if(show_keypad) show_history = false;
//remember start mode for when we save preferences
set_saved_mode();
}
void save_preferences(bool mode) {
FILE *file = NULL;
string filename = getLocalDir();
mkdir(filename.c_str(), S_IRWXU);
filename += "qalculate-kde.cfg";
file = fopen(filename.c_str(), "w+");
if(file == NULL) {
fprintf(stderr, i18n("Couldn't write preferences to\n%s"), filename.c_str());
return;
}
fprintf(file, "\n[General]\n");
fprintf(file, "version=%s\n", VERSION);
fprintf(file, "save_mode_on_exit=%i\n", save_mode_on_exit);
fprintf(file, "save_definitions_on_exit=%i\n", save_defs_on_exit);
fprintf(file, "load_global_definitions=%i\n", load_global_defs);
fprintf(file, "fetch_exchange_rates_at_startup=%i\n", fetch_exchange_rates_at_startup);
fprintf(file, "close_to_system_tray=%i\n", close_to_systray);
fprintf(file, "show_keypad=%i\n", mainWin->keypadButton->isOn() || (rpn_mode && show_keypad && mainWin->stackButton->isOn()));
fprintf(file, "show_history=%i\n", mainWin->historyButton->isOn() || (rpn_mode && show_history && mainWin->stackButton->isOn()));
fprintf(file, "show_stack=%i\n", rpn_mode ? mainWin->stackButton->isOn() : show_stack);
fprintf(file, "rpn_keypad_only=%i\n", rpn_keypad_only);
fprintf(file, "display_expression_status=%i\n", display_expression_status);
fprintf(file, "enable_expression_completion=%i\n", ((QalculateExpressionEdit*) expressionWidget)->completionEnabled());
if(use_icon_buttons >= 0) fprintf(file, "use_icon_buttons=%i\n", use_icon_buttons);
fprintf(file, "use_unicode_signs=%i\n", printops.use_unicode_signs);
fprintf(file, "lower_case_numbers=%i\n", printops.lower_case_numbers);
fprintf(file, "lower_case_e=%i\n", printops.lower_case_e);
fprintf(file, "base_display=%i\n", printops.base_display);
fprintf(file, "spell_out_logical_operators=%i\n", printops.spell_out_logical_operators);
fprintf(file, "dot_as_separator=%i\n", evalops.parse_options.dot_as_separator);
fprintf(file, "use_custom_result_font=%i\n", use_custom_result_font);
fprintf(file, "use_custom_expression_font=%i\n", use_custom_expression_font);
fprintf(file, "use_custom_status_font=%i\n", use_custom_status_font);
fprintf(file, "custom_result_font=%s\n", custom_result_font.ascii());
fprintf(file, "custom_expression_font=%s\n", custom_expression_font.ascii());
fprintf(file, "custom_status_font=%s\n", custom_status_font.ascii());
if(status_error_color != QColor("red")) fprintf(file, "status_error_color=%s\n", status_error_color.name().ascii());
if(status_warning_color != QColor("blue")) fprintf(file, "status_warning_color=%s\n", status_warning_color.name().ascii());
fprintf(file, "multiplication_sign=%i\n", printops.multiplication_sign);
fprintf(file, "division_sign=%i\n", printops.division_sign);
for (QStringList::Iterator it = ((QalculateExpressionEdit*) expressionWidget)->expression_history.begin(); it != ((QalculateExpressionEdit*) expressionWidget)->expression_history.end(); ++it) {
fprintf(file, "expression_history=%s\n", (*it).ascii());
}
int lines = 50;
bool end_after_result = false;
bool doend = false;
for(QValueVector<QString>::size_type i = 0; i < inhistory.size() && !doend; i++) {
switch(inhistory_type[i]) {
case QALCULATE_HISTORY_EXPRESSION: {
fprintf(file, "history_expression=");
break;
}
case QALCULATE_HISTORY_TRANSFORMATION: {
fprintf(file, "history_transformation=");
break;
}
case QALCULATE_HISTORY_RESULT: {
fprintf(file, "history_result=");
lines--;
if(end_after_result) doend = true;
break;
}
case QALCULATE_HISTORY_RESULT_APPROXIMATE: {
fprintf(file, "history_result_approximate=");
lines--;
if(end_after_result) doend = true;
break;
}
case QALCULATE_HISTORY_PARSE: {
fprintf(file, "history_parse=");
lines--;
if(lines < 0) end_after_result = true;
break;
}
case QALCULATE_HISTORY_PARSE_APPROXIMATE: {
fprintf(file, "history_parse_approximate=");
lines--;
if(lines < 0) end_after_result = true;
break;
}
case QALCULATE_HISTORY_REGISTER_MOVED: {
fprintf(file, "history_register_moved=");
break;
}
case QALCULATE_HISTORY_WARNING: {
fprintf(file, "history_warning=");
lines--;
break;
}
case QALCULATE_HISTORY_ERROR: {
fprintf(file, "history_error=");
lines--;
break;
}
case QALCULATE_HISTORY_OLD: {
fprintf(file, "history_old=");
lines--;
if(lines < 0) doend = true;
break;
}
}
if(inhistory[i].find("<br>") < 0) {
fprintf(file, "%s\n", inhistory[i].ascii());
} else {
QStringList slist = QStringList::split("<br>", inhistory[i], true);
for(QStringList::size_type i2 = 0; i2 < slist.size(); i2++) {
if(i2 == 0) fprintf(file, "%s\n", slist[i2].ascii());
else fprintf(file, "history_continued=%s\n", slist[i2].ascii());
}
}
}
fprintf(file, "recent_functions=");
for(int i = (int) (recent_functions.size()) - 1; i >= 0; i--) {
fprintf(file, "%s", recent_functions[i]->referenceName().c_str());
if(i != 0) fprintf(file, ",");
}
fprintf(file, "\n");
fprintf(file, "recent_variables=");
for(int i = (int) (recent_variables.size()) - 1; i >= 0; i--) {
fprintf(file, "%s", recent_variables[i]->referenceName().c_str());
if(i != 0) fprintf(file, ",");
}
fprintf(file, "\n");
fprintf(file, "recent_units=");
for(int i = (int) (recent_units.size()) - 1; i >= 0; i--) {
fprintf(file, "%s", recent_units[i]->referenceName().c_str());
if(i != 0) fprintf(file, ",");
}
fprintf(file, "\n");
if(mode)
set_saved_mode();
for(size_t i = 1; i < modes.size(); i++) {
if(i == 1) {
fprintf(file, "\n[Mode]\n");
} else {
fprintf(file, "\n[Mode %s]\n", modes[i].name.ascii());
if(!modes[i].shortcut.toString().isNull()) fprintf(file, "shortcut=%s\n", modes[i].shortcut.toString().ascii());
}
fprintf(file, "min_deci=%i\n", modes[i].po.min_decimals);
fprintf(file, "use_min_deci=%i\n", modes[i].po.use_min_decimals);
fprintf(file, "max_deci=%i\n", modes[i].po.max_decimals);
fprintf(file, "use_max_deci=%i\n", modes[i].po.use_max_decimals);
fprintf(file, "precision=%i\n", modes[i].precision);
fprintf(file, "min_exp=%i\n", modes[i].po.min_exp);
fprintf(file, "negative_exponents=%i\n", modes[i].po.negative_exponents);
fprintf(file, "sort_minus_last=%i\n", modes[i].po.sort_options.minus_last);
fprintf(file, "number_fraction_format=%i\n", modes[i].po.number_fraction_format);
fprintf(file, "use_prefixes=%i\n", modes[i].po.use_unit_prefixes);
fprintf(file, "abbreviate_names=%i\n", modes[i].po.abbreviate_names);
fprintf(file, "all_prefixes_enabled=%i\n", modes[i].po.use_all_prefixes);
fprintf(file, "denominator_prefix_enabled=%i\n", modes[i].po.use_denominator_prefix);
fprintf(file, "place_units_separately=%i\n", modes[i].po.place_units_separately);
fprintf(file, "auto_post_conversion=%i\n", modes[i].eo.auto_post_conversion);
fprintf(file, "number_base=%i\n", modes[i].po.base);
fprintf(file, "number_base_expression=%i\n", modes[i].eo.parse_options.base);
fprintf(file, "read_precision=%i\n", modes[i].eo.parse_options.read_precision);
fprintf(file, "assume_denominators_nonzero=%i\n", modes[i].eo.assume_denominators_nonzero);
fprintf(file, "warn_about_denominators_assumed_nonzero=%i\n", modes[i].eo.warn_about_denominators_assumed_nonzero);
fprintf(file, "structuring=%i\n", modes[i].eo.structuring);
fprintf(file, "angle_unit=%i\n", modes[i].eo.parse_options.angle_unit);
fprintf(file, "functions_enabled=%i\n", modes[i].eo.parse_options.functions_enabled);
fprintf(file, "variables_enabled=%i\n", modes[i].eo.parse_options.variables_enabled);
fprintf(file, "calculate_functions=%i\n", modes[i].eo.calculate_functions);
fprintf(file, "calculate_variables=%i\n", modes[i].eo.calculate_variables);
fprintf(file, "sync_units=%i\n", modes[i].eo.sync_units);
fprintf(file, "unknownvariables_enabled=%i\n", modes[i].eo.parse_options.unknowns_enabled);
fprintf(file, "units_enabled=%i\n", modes[i].eo.parse_options.units_enabled);
fprintf(file, "allow_complex=%i\n", modes[i].eo.allow_complex);
fprintf(file, "allow_infinite=%i\n", modes[i].eo.allow_infinite);
fprintf(file, "indicate_infinite_series=%i\n", modes[i].po.indicate_infinite_series);
fprintf(file, "show_ending_zeroes=%i\n", modes[i].po.show_ending_zeroes);
fprintf(file, "round_halfway_to_even=%i\n", modes[i].po.round_halfway_to_even);
fprintf(file, "approximation=%i\n", modes[i].eo.approximation);
fprintf(file, "in_rpn_mode=%i\n", modes[i].rpn_mode);
fprintf(file, "rpn_syntax=%i\n", modes[i].eo.parse_options.rpn);
fprintf(file, "limit_implicit_multiplication=%i\n", modes[i].eo.parse_options.limit_implicit_multiplication);
fprintf(file, "spacious=%i\n", modes[i].po.spacious);
fprintf(file, "excessive_parenthesis=%i\n", modes[i].po.excessive_parenthesis);
fprintf(file, "short_multiplication=%i\n", modes[i].po.short_multiplication);
fprintf(file, "default_assumption_type=%i\n", modes[i].at);
fprintf(file, "default_assumption_sign=%i\n", modes[i].as);
}
fprintf(file, "\n[Plotting]\n");
fprintf(file, "plot_legend_placement=%i\n", default_plot_legend_placement);
fprintf(file, "plot_style=%i\n", default_plot_style);
fprintf(file, "plot_smoothing=%i\n", default_plot_smoothing);
fprintf(file, "plot_display_grid=%i\n", default_plot_display_grid);
fprintf(file, "plot_full_border=%i\n", default_plot_full_border);
fprintf(file, "plot_min=%s\n", default_plot_min.ascii());
fprintf(file, "plot_max=%s\n", default_plot_max.ascii());
fprintf(file, "plot_step=%s\n", default_plot_step.ascii());
fprintf(file, "plot_sampling_rate=%i\n", default_plot_sampling_rate);
fprintf(file, "plot_use_sampling_rate=%i\n", default_plot_use_sampling_rate);
fprintf(file, "plot_variable=%s\n", default_plot_variable.ascii());
fprintf(file, "plot_rows=%i\n", default_plot_rows);
fprintf(file, "plot_type=%i\n", default_plot_type);
fprintf(file, "plot_color=%i\n", default_plot_color);
fprintf(file, "enable_plot_expression_completion=%i\n", enable_plot_expression_completion);
fclose(file);
}

@ -0,0 +1,42 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef PREFERENCES_H
#define PREFERENCES_H
enum {
QALCULATE_HISTORY_EXPRESSION,
QALCULATE_HISTORY_TRANSFORMATION,
QALCULATE_HISTORY_RESULT,
QALCULATE_HISTORY_RESULT_APPROXIMATE,
QALCULATE_HISTORY_PARSE,
QALCULATE_HISTORY_PARSE_APPROXIMATE,
QALCULATE_HISTORY_WARNING,
QALCULATE_HISTORY_ERROR,
QALCULATE_HISTORY_OLD,
QALCULATE_HISTORY_REGISTER_MOVED
};
void save_mode();
void load_preferences();
void save_preferences(bool mode = false);
#endif

@ -0,0 +1,13 @@
[Desktop Entry]
Name=Qalculate!
GenericName=Scientific Calculator
Exec=qalculate-kde
Icon=qalculate_kde
Type=Application
DocPath=qalculate_kde/index.html
Categories=Qt;KDE;Utility;Science;
Terminal=false
X-DCOP-ServiceType=Unique
X-DCOP-ServiceName=qalculate_kde
X-KDE-StartupNotify=true
Comment=Powerful and easy to use desktop calculator

@ -0,0 +1,307 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculate_kde_utils.h"
#include <qwidget.h>
#include <qlabel.h>
#include <qlineedit.h>
#include <qstring.h>
#include <qfont.h>
#include <qfontmetrics.h>
#include "kqalculate.h"
tree_struct function_cats, unit_cats, variable_cats;
vector<void*> ia_units, ia_variables, ia_functions;
vector<MathFunction*> recent_functions;
vector<Variable*> recent_variables;
vector<Unit*> recent_units;
extern PrintOptions printops;
extern KnownVariable *vans[5];
extern QWidget *topWidget;
extern KQalculate *mainWin;
void insert_text_in_expression(const QString &str) {
mainWin->insert_text(str);
}
bool is_answer_variable(Variable *v) {
return v == vans[0] || v == vans[1] || v == vans[2] || v == vans[3] || v == vans[4];
}
QString get_value_string(const MathStructure &mstruct_, bool rlabel, Prefix *prefix) {
printops.allow_non_usable = rlabel;
printops.prefix = prefix;
QString str = CALCULATOR->printMathStructureTimeOut(mstruct_, 100, printops).c_str();
printops.allow_non_usable = false;
printops.prefix = NULL;
return str;
}
void set_name_label_and_entry(ExpressionItem *item, QLineEdit *entry, QLabel *label) {
const ExpressionName *ename = &item->getName(1);
entry->setText(ename->name.c_str());
if(item->countNames() > 1) {
QString str = "+ ";
for(size_t i = 2; i <= item->countNames(); i++) {
if(i > 2) str += ", ";
str += item->getName(i).name.c_str();
}
label->setText(str);
}
}
bool can_display_unicode_string_function(const char *str, void *arg) {
if(!arg) arg = (void*) topWidget;
QFontMetrics fm(((QWidget*) arg)->fontMetrics());
QString qstr(str);
const QChar *qchars = qstr.unicode();
for(uint i = 0; i < qstr.length(); i++) {
if(!fm.inFont(qchars[i])) return false;
}
return true;
}
void generate_units_tree_struct() {
size_t cat_i, cat_i_prev;
bool b;
string str, cat, cat_sub;
Unit *u = NULL;
unit_cats.items.clear();
unit_cats.objects.clear();
unit_cats.parent = NULL;
ia_units.clear();
list<tree_struct>::iterator it;
for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
if(!CALCULATOR->units[i]->isActive()) {
b = false;
for(size_t i3 = 0; i3 < ia_units.size(); i3++) {
u = (Unit*) ia_units[i3];
if(CALCULATOR->units[i]->title() < u->title()) {
b = true;
ia_units.insert(ia_units.begin() + i3, (void*) CALCULATOR->units[i]);
break;
}
}
if(!b) ia_units.push_back((void*) CALCULATOR->units[i]);
} else {
tree_struct *item = &unit_cats;
if(!CALCULATOR->units[i]->category().empty()) {
cat = CALCULATOR->units[i]->category();
cat_i = cat.find("/"); cat_i_prev = 0;
b = false;
while(true) {
if(cat_i == string::npos) {
cat_sub = cat.substr(cat_i_prev, cat.length() - cat_i_prev);
} else {
cat_sub = cat.substr(cat_i_prev, cat_i - cat_i_prev);
}
b = false;
for(it = item->items.begin(); it != item->items.end(); ++it) {
if(cat_sub == it->item) {
item = &*it;
b = true;
break;
}
}
if(!b) {
tree_struct cat;
item->items.push_back(cat);
it = item->items.end();
--it;
it->parent = item;
item = &*it;
item->item = cat_sub;
}
if(cat_i == string::npos) {
break;
}
cat_i_prev = cat_i + 1;
cat_i = cat.find("/", cat_i_prev);
}
}
b = false;
for(size_t i3 = 0; i3 < item->objects.size(); i3++) {
u = (Unit*) item->objects[i3];
if(CALCULATOR->units[i]->title() < u->title()) {
b = true;
item->objects.insert(item->objects.begin() + i3, (void*) CALCULATOR->units[i]);
break;
}
}
if(!b) item->objects.push_back((void*) CALCULATOR->units[i]);
}
}
unit_cats.sort();
}
void generate_variables_tree_struct() {
size_t cat_i, cat_i_prev;
bool b;
string str, cat, cat_sub;
Variable *v = NULL;
variable_cats.items.clear();
variable_cats.objects.clear();
variable_cats.parent = NULL;
ia_variables.clear();
list<tree_struct>::iterator it;
for(size_t i = 0; i < CALCULATOR->variables.size(); i++) {
if(!CALCULATOR->variables[i]->isActive()) {
//deactivated variable
b = false;
for(size_t i3 = 0; i3 < ia_variables.size(); i3++) {
v = (Variable*) ia_variables[i3];
if(CALCULATOR->variables[i]->title() < v->title()) {
b = true;
ia_variables.insert(ia_variables.begin() + i3, (void*) CALCULATOR->variables[i]);
break;
}
}
if(!b) ia_variables.push_back((void*) CALCULATOR->variables[i]);
} else {
tree_struct *item = &variable_cats;
if(!CALCULATOR->variables[i]->category().empty()) {
cat = CALCULATOR->variables[i]->category();
cat_i = cat.find("/"); cat_i_prev = 0;
b = false;
while(true) {
if(cat_i == string::npos) {
cat_sub = cat.substr(cat_i_prev, cat.length() - cat_i_prev);
} else {
cat_sub = cat.substr(cat_i_prev, cat_i - cat_i_prev);
}
b = false;
for(it = item->items.begin(); it != item->items.end(); ++it) {
if(cat_sub == it->item) {
item = &*it;
b = true;
break;
}
}
if(!b) {
tree_struct cat;
item->items.push_back(cat);
it = item->items.end();
--it;
it->parent = item;
item = &*it;
item->item = cat_sub;
}
if(cat_i == string::npos) {
break;
}
cat_i_prev = cat_i + 1;
cat_i = cat.find("/", cat_i_prev);
}
}
b = false;
for(size_t i3 = 0; i3 < item->objects.size(); i3++) {
v = (Variable*) item->objects[i3];
if(CALCULATOR->variables[i]->title() < v->title()) {
b = true;
item->objects.insert(item->objects.begin() + i3, (void*) CALCULATOR->variables[i]);
break;
}
}
if(!b) item->objects.push_back((void*) CALCULATOR->variables[i]);
}
}
variable_cats.sort();
}
void generate_functions_tree_struct() {
size_t cat_i, cat_i_prev;
bool b;
string str, cat, cat_sub;
MathFunction *f = NULL;
function_cats.items.clear();
function_cats.objects.clear();
function_cats.parent = NULL;
ia_functions.clear();
list<tree_struct>::iterator it;
for(size_t i = 0; i < CALCULATOR->functions.size(); i++) {
if(!CALCULATOR->functions[i]->isActive()) {
//deactivated function
b = false;
for(size_t i3 = 0; i3 < ia_functions.size(); i3++) {
f = (MathFunction*) ia_functions[i3];
if(CALCULATOR->functions[i]->title() < f->title()) {
b = true;
ia_functions.insert(ia_functions.begin() + i3, (void*) CALCULATOR->functions[i]);
break;
}
}
if(!b) ia_functions.push_back((void*) CALCULATOR->functions[i]);
} else {
tree_struct *item = &function_cats;
if(!CALCULATOR->functions[i]->category().empty()) {
cat = CALCULATOR->functions[i]->category();
cat_i = cat.find("/"); cat_i_prev = 0;
b = false;
while(true) {
if(cat_i == string::npos) {
cat_sub = cat.substr(cat_i_prev, cat.length() - cat_i_prev);
} else {
cat_sub = cat.substr(cat_i_prev, cat_i - cat_i_prev);
}
b = false;
for(it = item->items.begin(); it != item->items.end(); ++it) {
if(cat_sub == it->item) {
item = &*it;
b = true;
break;
}
}
if(!b) {
tree_struct cat;
item->items.push_back(cat);
it = item->items.end();
--it;
it->parent = item;
item = &*it;
item->item = cat_sub;
}
if(cat_i == string::npos) {
break;
}
cat_i_prev = cat_i + 1;
cat_i = cat.find("/", cat_i_prev);
}
}
b = false;
for(size_t i3 = 0; i3 < item->objects.size(); i3++) {
f = (MathFunction*) item->objects[i3];
if(CALCULATOR->functions[i]->title() < f->title()) {
b = true;
item->objects.insert(item->objects.begin() + i3, (void*) CALCULATOR->functions[i]);
break;
}
}
if(!b) item->objects.push_back((void*) CALCULATOR->functions[i]);
}
}
function_cats.sort();
}

@ -0,0 +1,74 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATE_KDE_UTILS_H
#define QALCULATE_KDE_UTILS_H
#include <libqalculate/qalculate.h>
#undef insertItem
#undef addItem
#undef setItem
#undef getItem
#include <qstring.h>
#include <kshortcut.h>
class QLabel;
class QLineEdit;
struct tree_struct {
string item;
list<tree_struct> items;
list<tree_struct>::iterator it;
list<tree_struct>::reverse_iterator rit;
vector<void*> objects;
tree_struct *parent;
void sort() {
items.sort();
for(list<tree_struct>::iterator it = items.begin(); it != items.end(); ++it) {
it->sort();
}
}
bool operator < (tree_struct &s1) const {
return item < s1.item;
}
};
struct mode_struct {
PrintOptions po;
EvaluationOptions eo;
AssumptionType at;
AssumptionSign as;
int precision;
QString name;
bool rpn_mode;
KShortcut shortcut;
};
void insert_text_in_expression(const QString &str);
bool is_answer_variable(Variable *v);
QString get_value_string(const MathStructure &mstruct_, bool rlabel = false, Prefix *prefix = NULL);
void set_name_label_and_entry(ExpressionItem *item, QLineEdit *entry, QLabel *label);
bool can_display_unicode_string_function(const char *str, void *arg);
void generate_units_tree_struct();
void generate_functions_tree_struct();
void generate_variables_tree_struct();
size_t save_mode_as(QString name, bool *new_mode = NULL);
#endif

@ -0,0 +1,168 @@
<!DOCTYPE kpartgui>
<kpartgui name="kqalculate">
<MenuBar>
<Menu name="file"><text>&amp;File</text>
<Menu name="new" icon="filenew"><text>&amp;New</text>
<Action name="new_variable"/>
<Action name="new_matrix"/>
<Action name="new_vector"/>
<Action name="new_unknown_variable"/>
<Action name="new_function"/>
<Action name="new_data_set"/>
<Action name="new_unit"/>
</Menu>
<Action name="import_csv_file"/>
<Action name="export_csv_file"/>
<Action name="store_result"/>
<Action name="save_as_image"/>
<Separator/>
<Action name="save_definitions"/>
<Action name="update_exchange_rates"/>
<Separator/>
<Action name="plot_functions_data"/>
<Action name="convert_number_bases"/>
<Action name="periodic_table"/>
<Separator/>
<Action name="quit"/>
</Menu>
<Menu name="edit"><text>&amp;Edit</text>
<Action name="manage_variables"/>
<Action name="manage_functions"/>
<Action name="manage_units"/>
<Action name="manage_data_sets"/>
<Separator/>
<Action name="factorize"/>
<Action name="simplify"/>
<Action name="set_unknowns"/>
<Menu name="set_prefix"><text>&amp;Set Prefix</text>
</Menu>
<Menu name="convert_to_unit"><text>&amp;Convert To Unit</text>
</Menu>
<Action name="convert_to_unit_expression"/>
<Action name="convert_to_base_units"/>
<Action name="convert_to_best_unit"/>
<Separator/>
<Action name="insert_matrix"/>
<Action name="insert_vector"/>
<Separator/>
<Action name="copy_result"/>
<Separator/>
<Action name="preferences"/>
<Action name="keybindings"/>
<Action name="configure_global_shortcuts"/>
</Menu>
<Menu name="mode"><text>&amp;Mode</text>
<Menu name="number_base"><text>Number Base</text>
<Action name="set_base"/>
<Separator/>
<Action name="number_base_binary"/>
<Action name="number_base_octal"/>
<Action name="number_base_decimal"/>
<Action name="number_base_hexadecimal"/>
<Action name="number_base_sexagesimal"/>
<Action name="number_base_time_format"/>
<Action name="number_base_roman_numerals"/>
<Action name="number_base_other"/>
</Menu>
<Menu name="numerical_display"><text>Numerical Display</text>
<Action name="numerical_display_normal"/>
<Action name="numerical_display_engineering"/>
<Action name="numerical_display_scientific"/>
<Action name="numerical_display_purely_scientific"/>
<Action name="numerical_display_simple"/>
<Separator/>
<Action name="indicate_infinite_series"/>
<Action name="show_ending_zeroes"/>
<Action name="round_halfway_numbers_to_even"/>
<Action name="negative_exponents"/>
<Action name="sort_minus_last"/>
</Menu>
<Menu name="fractional_display"><text>Fractional Display</text>
<Action name="fractional_display_decimal"/>
<Action name="fractional_display_decimal_try_exact"/>
<Action name="fractional_display_fraction"/>
<Action name="fractional_display_combined"/>
</Menu>
<Menu name="unit_display"><text>Unit Display</text>
<Action name="enable_prefixes"/>
<Action name="enable_use_of_all_prefixes"/>
<Action name="enable_denominator_prefixes"/>
<Action name="place_units_separately"/>
<Separator/>
<Action name="auto_no_conversion"/>
<Action name="auto_convert_to_base_units"/>
<Action name="auto_convert_to_best_unit"/>
</Menu>
<Menu name="angle_unit"><text>Angle Unit</text>
<Action name="angle_unit_degrees"/>
<Action name="angle_unit_radians"/>
<Action name="angle_unit_gradians"/>
<Action name="angle_unit_none"/>
</Menu>
<Action name="abbreviate_names"/>
<Separator/>
<Menu name="enabled_objects"><text>Enabled Objects</text>
<Action name="enable_variables"/>
<Action name="enable_functions"/>
<Action name="enable_units"/>
<Action name="enable_unknowns"/>
<Separator/>
<Action name="calculate_variables"/>
<Separator/>
<Action name="allow_complex_result"/>
<Action name="allow_infinite_result"/>
</Menu>
<Separator/>
<Menu name="approximation"><text>Approximation</text>
<Action name="approximation_try_exact"/>
<Action name="approximation_always_exact"/>
<Action name="approximation_approximate"/>
</Menu>
<Menu name="assumptions"><text>Assumptions</text>
<Action name="assumption_type_unknown"/>
<Action name="assumption_type_nonmatrix"/>
<Action name="assumption_type_number"/>
<Action name="assumption_type_complex"/>
<Action name="assumption_type_real"/>
<Action name="assumption_type_rational"/>
<Action name="assumption_type_integer"/>
<Separator/>
<Action name="assumption_sign_unknown"/>
<Action name="assumption_sign_non_zero"/>
<Action name="assumption_sign_positive"/>
<Action name="assumption_sign_non_negative"/>
<Action name="assumption_sign_negative"/>
<Action name="assumption_sign_non_positive"/>
</Menu>
<Menu name="algebraic_mode"><text>Algebraic Mode</text>
<Action name="algebraic_mode_simplify"/>
<Action name="algebraic_mode_factorize"/>
<Action name="algebraic_mode_none"/>
<Separator/>
<Action name="non_zero_denominators"/>
<Action name="warn_about_denominators_assumed_nonzero"/>
</Menu>
<Separator/>
<Action name="read_precision"/>
<Action name="limit_implicit_multiplication"/>
<Action name="rpn_mode"/>
<Action name="rpn_syntax"/>
<Separator/>
<Action name="precision"/>
<Action name="decimals"/>
<Separator/>
<Menu name="modes"><text>Meta Modes</text>
<Separator/>
<Action name="save_mode_as"/>
<Action name="delete_mode"/>
</Menu>
<Action name="save_mode"/>
</Menu>
<Menu name="functions"><text>Fu&amp;nctions</text>
</Menu>
<Menu name="variables"><text>&amp;Variables</text>
</Menu>
<Menu name="units"><text>&amp;Units</text>
</Menu>
</MenuBar>
</kpartgui>

@ -0,0 +1,37 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculatebuttonwithdata.h"
QalculateButtonWithData::QalculateButtonWithData(void *data, const QString & text, QWidget *parent, const char *name) : QPushButton(text, parent, name) {
user_data = data;
QObject::connect(this, SIGNAL(clicked()), this, SLOT(emitClickedWithData()));
}
QalculateButtonWithData::QalculateButtonWithData(void *data, const QIconSet & icon, const QString & text, QWidget * parent, const char * name) : QPushButton(icon, text, parent, name) {
user_data = data;
QObject::connect(this, SIGNAL(clicked()), this, SLOT(emitClickedWithData()));
}
QalculateButtonWithData::~QalculateButtonWithData() {}
void QalculateButtonWithData::emitClickedWithData() {
emit clickedWithData(user_data);
}
#include "qalculatebuttonwithdata.moc"

@ -0,0 +1,48 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEBUTTONWITHDATA_H
#define QALCULATEBUTTONWITHDATA_H
#include <qpushbutton.h>
/**
@author Niklas Knutsson
*/
class QalculateButtonWithData : public QPushButton {
Q_OBJECT
public:
QalculateButtonWithData(void *data, const QString & text, QWidget *parent, const char *name = 0);
QalculateButtonWithData(void *data, const QIconSet & icon, const QString & text, QWidget * parent, const char * name = 0);
virtual ~QalculateButtonWithData();
void *user_data;
protected slots:
void emitClickedWithData();
signals:
void clickedWithData(void*);
};
#endif

@ -0,0 +1,122 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateconvertnumberbasesdialog.h"
#include "qalculate_kde_utils.h"
#include <klocale.h>
#include <qgrid.h>
#include <qlabel.h>
#include <klineedit.h>
#include <qpushbutton.h>
extern EvaluationOptions evalops;
QalculateConvertNumberBasesDialog::QalculateConvertNumberBasesDialog(QWidget *parent, const char *name)
: KDialogBase(parent, name, false, i18n("Number Bases"), Close, Close) {
actionButton(Close)->setAutoDefault(false);
actionButton(Close)->setDefault(false);
QGrid *grid = makeGridMainWidget(2, Qt::Horizontal);
new QLabel(i18n("Decimal:"), grid);
decimalEdit = new KLineEdit(grid);
decimalEdit->setAlignment(Qt::AlignRight);
QObject::connect(decimalEdit, SIGNAL(textChanged(const QString&)), this, SLOT(setDecimalValue(const QString&)));
new QLabel(i18n("Binary:"), grid);
binaryEdit = new KLineEdit(grid);
binaryEdit->setAlignment(Qt::AlignRight);
QObject::connect(binaryEdit, SIGNAL(textChanged(const QString&)), this, SLOT(setBinaryValue(const QString&)));
new QLabel(i18n("Octal:"), grid);
octalEdit = new KLineEdit(grid);
octalEdit->setAlignment(Qt::AlignRight);
QObject::connect(octalEdit, SIGNAL(textChanged(const QString&)), this, SLOT(setOctalValue(const QString&)));
new QLabel(i18n("Hexadecimal:"), grid);
hexadecimalEdit = new KLineEdit(grid);
hexadecimalEdit->setAlignment(Qt::AlignRight);
QObject::connect(hexadecimalEdit, SIGNAL(textChanged(const QString&)), this, SLOT(setHexadecimalValue(const QString&)));
decimalEdit->setFocus();
}
QalculateConvertNumberBasesDialog::~QalculateConvertNumberBasesDialog() {}
void QalculateConvertNumberBasesDialog::setDecimalValue(const QString &qstr) {
string str = qstr.ascii();
remove_blank_ends(str);
if(str.empty()) return;
if(is_in(OPERATORS EXP, str[str.length() - 1])) return;
EvaluationOptions eo;
eo.parse_options.angle_unit = evalops.parse_options.angle_unit;
MathStructure value = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo);
updateEntries(&value, 10);
}
void QalculateConvertNumberBasesDialog::setBinaryValue(const QString &qstr) {
string str = qstr.ascii();
remove_blank_ends(str);
if(str.empty()) return;
if(is_in(OPERATORS EXP, str[str.length() - 1])) return;
EvaluationOptions eo;
eo.parse_options.base = BASE_BINARY;
eo.parse_options.angle_unit = evalops.parse_options.angle_unit;
MathStructure value = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo);
updateEntries(&value, 2);
}
void QalculateConvertNumberBasesDialog::setOctalValue(const QString &qstr) {
string str = qstr.ascii();
remove_blank_ends(str);
if(str.empty()) return;
if(is_in(OPERATORS EXP, str[str.length() - 1])) return;
EvaluationOptions eo;
eo.parse_options.base = BASE_OCTAL;
eo.parse_options.angle_unit = evalops.parse_options.angle_unit;
MathStructure value = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo);
updateEntries(&value, 8);
}
void QalculateConvertNumberBasesDialog::setHexadecimalValue(const QString &qstr) {
string str = qstr.ascii();
remove_blank_ends(str);
if(str.empty()) return;
if(is_in(OPERATORS EXP, str[str.length() - 1])) return;
EvaluationOptions eo;
eo.parse_options.angle_unit = evalops.parse_options.angle_unit;
eo.parse_options.base = BASE_HEXADECIMAL;
MathStructure value = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo);
updateEntries(&value, 16);
}
void QalculateConvertNumberBasesDialog::updateEntries(const MathStructure *value, int base) {
decimalEdit->blockSignals(true);
binaryEdit->blockSignals(true);
octalEdit->blockSignals(true);
hexadecimalEdit->blockSignals(true);
PrintOptions po;
po.number_fraction_format = FRACTION_DECIMAL;
if(base != 10) {po.base = 10; decimalEdit->setText(value->print(po).c_str());}
if(base != 2) {po.base = 2; binaryEdit->setText(value->print(po).c_str());}
if(base != 8) {po.base = 8; octalEdit->setText(value->print(po).c_str());}
if(base != 16) {po.base = 16; hexadecimalEdit->setText(value->print(po).c_str());}
decimalEdit->blockSignals(false);
binaryEdit->blockSignals(false);
octalEdit->blockSignals(false);
hexadecimalEdit->blockSignals(false);
}
#include "qalculateconvertnumberbasesdialog.moc"

@ -0,0 +1,53 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATECONVERTNUMBERBASESDIALOG_H
#define QALCULATECONVERTNUMBERBASESDIALOG_H
#include <kdialogbase.h>
class KLineEdit;
class MathStructure;
/**
@author Niklas Knutsson
*/
class QalculateConvertNumberBasesDialog : public KDialogBase {
Q_OBJECT
public:
QalculateConvertNumberBasesDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateConvertNumberBasesDialog();
KLineEdit *binaryEdit, *octalEdit, *decimalEdit, *hexadecimalEdit;
public slots:
void setDecimalValue(const QString&);
void setBinaryValue(const QString&);
void setOctalValue(const QString&);
void setHexadecimalValue(const QString&);
protected:
void updateEntries(const MathStructure *value, int base);
};
#endif

@ -0,0 +1,205 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateconvertunitsdialog.h"
#include "qalculate_kde_utils.h"
#include <qlabel.h>
#include <klineedit.h>
#include <klocale.h>
#include <qhbox.h>
#include <klistview.h>
#include <klocale.h>
#include <qvbox.h>
#include <klistview.h>
#include <kmessagebox.h>
#include <qlayout.h>
#include <qpushbutton.h>
#include <qsplitter.h>
extern tree_struct unit_cats;
extern vector<void*> ia_units;
extern PrintOptions printops;
extern EvaluationOptions evalops;
QalculateConvertUnitsDialog::QalculateConvertUnitsDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Convert"), Ok | Apply | Cancel | Details, Ok, true) {
setButtonText(Details, i18n("Selector"));
selected_category = "";
block_unit_convert = true;
QVBox *box = makeVBoxMainWidget();
new QLabel(i18n("Unit expression:"), box);
unitExpressionEdit = new KLineEdit(box);
QVBox *box_d = new QVBox(this);
box_d->setSpacing(spacingHint());
new QWidget(box_d);
QSplitter *splitter = new QSplitter(Qt::Vertical, box_d);
splitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setDetailsWidget(box_d);
categoryView = new KListView(splitter);
categoryView->addColumn(i18n("Category"));
categoryView->setRootIsDecorated(false);
categoryView->setFullWidth(true);
unitView = new KListView(splitter);
unitView->addColumn(i18n("Unit"));
unitView->setRootIsDecorated(false);
unitView->setFullWidth(true);
unitExpressionEdit->setFocus();
connect(unitView, SIGNAL(selectionChanged()), this, SLOT(unitSelected()));
connect(categoryView, SIGNAL(selectionChanged()), this, SLOT(categorySelected()));
}
QalculateConvertUnitsDialog::~QalculateConvertUnitsDialog() {}
void QalculateConvertUnitsDialog::updateUnitTree() {
unitItems.clear();
categoryItems.clear();
categoryView->clear();
QListViewItem *i = new KListViewItem(categoryView, i18n("All")), *i2;
categoryItems[i] = i18n("All");
i->setOpen(true);
QString str;
tree_struct *item, *item2;
unit_cats.it = unit_cats.items.begin();
if(unit_cats.it != unit_cats.items.end()) {
item = &*unit_cats.it;
++unit_cats.it;
item->it = item->items.begin();
} else {
item = NULL;
}
str = "";
i2 = i;
while(item) {
str += "/";
str += item->item.c_str();
i = new KListViewItem(i2, item->item.c_str());
i->setOpen(false);
categoryItems[i] = str;
if(str == selected_category) {
categoryView->ensureItemVisible(i);
categoryView->setSelected(i, true);
}
while(item && item->it == item->items.end()) {
int str_i = str.findRev("/");
if(str_i < 0) {
str = "";
} else {
str.truncate(str_i);
}
item = item->parent;
i = i->parent();
i2 = i;
}
if(item) {
item2 = &*item->it;
if(item->it == item->items.begin())
i2 = i;
++item->it;
item = item2;
item->it = item->items.begin();
}
}
if(!unit_cats.objects.empty()) {
//add "Uncategorized" category if there are units without category
i = new KListViewItem(categoryView, i18n("Uncategorized"));
categoryItems[i] = i18n("Uncategorized");
if(selected_category == i18n("Uncategorized")) {
categoryView->ensureItemVisible(i);
categoryView->setSelected(i, true);
}
}
if(!categoryView->selectedItem()) {
//if no category has been selected (previously selected has been renamed/deleted), select "All"
selected_category = i18n("All");
QListViewItemIterator it(categoryView);
if(it.current())
categoryView->setSelected(it.current(), true);
}
}
void QalculateConvertUnitsDialog::unitSelected() {
QListViewItem *selected = unitView->selectedItem();
if(selected) {
Unit *u = unitItems[selected];
if(!CALCULATOR->stillHasUnit(u)) {
KMessageBox::error(this, i18n("Unit does not exist anymore."));
emit unitsChanged();
return;
}
unitExpressionEdit->setText(u->print(false, printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) unitExpressionEdit).c_str());
unitView->selectAll(false);
if(!block_unit_convert) actionButton(Apply)->animateClick();
}
}
void QalculateConvertUnitsDialog::addUnitTreeItem(Unit *u) {
QListViewItem *i = new KListViewItem(unitView, u->title(true).c_str());
unitItems[i] = u;
}
void QalculateConvertUnitsDialog::categorySelected() {
block_unit_convert = true;
QListViewItem *selected = categoryView->selectedItem();
bool no_cat = false, b_all = false;
unitView->clear();
unitItems.clear();
if(!selected) {
selected_category = "";
return;
}
selected_category = categoryItems[selected];
if(selected_category == i18n("All")) {
b_all = true;
} else if(selected_category == i18n("Uncategorized")) {
no_cat = true;
}
if(!b_all && !no_cat && selected_category[0] == '/') {
string str = selected_category.ascii();
str.erase(str.begin());
for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
if(CALCULATOR->units[i]->isActive() && !CALCULATOR->units[i]->isHidden() && CALCULATOR->units[i]->category().substr(0, selected_category.length() - 1) == str) {
addUnitTreeItem(CALCULATOR->units[i]);
}
}
} else {
string str = selected_category.ascii();
for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
if(CALCULATOR->units[i]->isActive() && !CALCULATOR->units[i]->isHidden() && (b_all || (no_cat && CALCULATOR->units[i]->category().empty()) || CALCULATOR->units[i]->category() == str)) {
addUnitTreeItem(CALCULATOR->units[i]);
}
}
}
block_unit_convert = false;
}
#include "qalculateconvertunitsdialog.moc"

@ -0,0 +1,67 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATECONVERTUNITSDIALOG_H
#define QALCULATECONVERTUNITSDIALOG_H
#include <kdialogbase.h>
#include <qmap.h>
class KLineEdit;
class Unit;
class KListView;
class QListViewItem;
/**
@author Niklas Knutsson
*/
class QalculateConvertUnitsDialog : public KDialogBase {
Q_OBJECT
public:
QalculateConvertUnitsDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateConvertUnitsDialog();
KLineEdit *unitExpressionEdit;
void addUnitTreeItem(Unit *f);
QMap<QListViewItem*, Unit*> unitItems;
QMap<QListViewItem*, QString> categoryItems;
KListView *categoryView;
KListView *unitView;
QString selected_category;
bool block_unit_convert;
public slots:
void updateUnitTree();
void unitSelected();
void categorySelected();
signals:
void unitsChanged();
};
#endif

@ -0,0 +1,506 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculatedatasetsdialog.h"
#include "qalculateeditdatasetdialog.h"
#include "qalculateeditdataobjectdialog.h"
#include "qalculate_kde_utils.h"
#include "qalculatebuttonwithdata.h"
#include <kpushbutton.h>
#include <qsplitter.h>
#include <qvbox.h>
#include <qhbox.h>
#include <qgrid.h>
#include <klistview.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <qlayout.h>
#include <qgroupbox.h>
#include <qscrollview.h>
#include <ktextbrowser.h>
#include <qlabel.h>
#include <kactivelabel.h>
#include <kiconloader.h>
#include <klineedit.h>
extern PrintOptions printops;
extern QWidget *expressionWidget;
QalculateDataSetsDialog::QalculateDataSetsDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Data Sets"), Close, Close, false) {
dataset_edit_dialog = NULL;
object_edit_dialog = NULL;
QVBox *box = makeVBoxMainWidget();
QSplitter *splitter = new QSplitter(Qt::Vertical, box);
QVBox *group1 = new QVBox(splitter);
QVBox *group2 = new QVBox(splitter);
splitter = new QSplitter(Qt::Horizontal, group1);
QWidget *widget = new QWidget(splitter);
widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
QVBoxLayout *vbox = new QVBoxLayout(widget, spacingHint(), spacingHint());
vbox->addWidget(new QLabel(i18n("Data Sets:"), widget));
dataSetsView = new KListView(widget);
vbox->addWidget(dataSetsView);
dataSetsView->addColumn(i18n("Data Set"));
dataSetsView->setRootIsDecorated(false);
QHBoxLayout *hbox = new QHBoxLayout(vbox);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
newDataSetButton = new QPushButton(i18n("New"), widget);
hbox->addWidget(newDataSetButton);
editDataSetButton = new QPushButton(i18n("Edit"), widget);
hbox->addWidget(editDataSetButton);
deleteDataSetButton = new QPushButton(i18n("Delete"), widget);
hbox->addWidget(deleteDataSetButton);
QVBox *vbox2 = new QVBox(splitter);
vbox2->setMargin(spacingHint());
vbox2->setSpacing(spacingHint());
new QLabel(i18n("Description:"), vbox2);
descriptionBrowser = new KTextBrowser(vbox2);
splitter = new QSplitter(Qt::Horizontal, group2);
widget = new QWidget(splitter);
widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
vbox = new QVBoxLayout(widget, spacingHint(), spacingHint());
vbox->addWidget(new QLabel(i18n("Objects:"), widget));
objectsView = new KListView(widget);
vbox->addWidget(objectsView);
objectsView->addColumn(i18n("Object"));
objectsView->setRootIsDecorated(false);
hbox = new QHBoxLayout(vbox);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
newObjectButton = new QPushButton(i18n("New"), widget);
hbox->addWidget(newObjectButton);
editObjectButton = new QPushButton(i18n("Edit"), widget);
hbox->addWidget(editObjectButton);
deleteObjectButton = new QPushButton(i18n("Delete"), widget);
hbox->addWidget(deleteObjectButton);
vbox2 = new QVBox(splitter);
vbox2->setMargin(spacingHint());
vbox2->setSpacing(spacingHint());
new QLabel(i18n("Attributes:"), vbox2);
attributesView = new QScrollView(vbox2);
attributesView->setResizePolicy(QScrollView::AutoOneFit);
attributesView->setFrameStyle(QFrame::NoFrame);
attributesGrid = new QGrid(3, Qt::Horizontal, attributesView->viewport());
attributesGrid->setSpacing(spacingHint());
attributesView->addChild(attributesGrid);
resize(QSize(675, 525).expandedTo(size()));
connect(newDataSetButton, SIGNAL(clicked()), this, SLOT(newDataSet()));
connect(editDataSetButton, SIGNAL(clicked()), this, SLOT(editDataSet()));
connect(deleteDataSetButton, SIGNAL(clicked()), this, SLOT(deleteDataSet()));
connect(dataSetsView, SIGNAL(selectionChanged()), this, SLOT(dataSetSelected()));
connect(dataSetsView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(dataSetDoubleClicked(QListViewItem*)));
connect(newObjectButton, SIGNAL(clicked()), this, SLOT(newObject()));
connect(editObjectButton, SIGNAL(clicked()), this, SLOT(editObject()));
connect(deleteObjectButton, SIGNAL(clicked()), this, SLOT(deleteObject()));
connect(objectsView, SIGNAL(selectionChanged()), this, SLOT(objectSelected()));
connect(objectsView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(objectDoubleClicked(QListViewItem*)));
}
QalculateDataSetsDialog::~QalculateDataSetsDialog() {}
void QalculateDataSetsDialog::updateDataSetTree() {
dataSetItems.clear();
objectItems.clear();
dataSetsView->clear();
DataSet *ds;
QListViewItem *i;
bool b = false;
dataSetsView->blockSignals(true);
for(size_t index = 1; ; index++) {
ds = CALCULATOR->getDataSet(index);
if(!ds) break;
i = new KListViewItem(dataSetsView, ds->title().c_str());
dataSetItems[i] = ds;
if(ds == selected_dataset) {
dataSetsView->blockSignals(false);
dataSetsView->setSelected(i, true);
dataSetsView->blockSignals(true);
b = true;
}
}
dataSetsView->blockSignals(false);
if(!b) {
dataSetsView->selectAll(false);
selected_dataset = NULL;
}
}
#define UPDATE_SELECTED_DATASET QListViewItem *i3 = dataSetsView->selectedItem(); if(!i3) return; selected_dataset = dataSetItems[i3]; if(!selected_dataset) return;
#define UPDATE_SELECTED_OBJECT QListViewItem *i2 = objectsView->selectedItem(); if(!i2) return; selected_object = objectItems[i2]; if(!selected_object) return;
#define CHECK_IF_DATASET_STILL_THERE if(!CALCULATOR->stillHasFunction(selected_dataset)) {KMessageBox::error(this, i18n("Data set does not exist anymore.")); emit dataSetsChanged(); return;}
void QalculateDataSetsDialog::deleteDataSet() {
UPDATE_SELECTED_DATASET
CHECK_IF_DATASET_STILL_THERE
if(selected_dataset->isLocal()) {
selected_object = NULL;
//ensure that all references are removed in Calculator
selected_dataset->destroy();
//update menus and trees
emit dataSetsChanged();
}
}
void QalculateDataSetsDialog::editDataSet() {
UPDATE_SELECTED_DATASET
CHECK_IF_DATASET_STILL_THERE
if(!dataset_edit_dialog) {
dataset_edit_dialog = new QalculateEditDataSetDialog(this);
}
DataSet *ds = dataset_edit_dialog->editDataSet(selected_dataset);
if(ds) {
selected_dataset = ds;
emit dataSetsChanged();
}
}
void QalculateDataSetsDialog::newDataSet() {
if(!dataset_edit_dialog) {
dataset_edit_dialog = new QalculateEditDataSetDialog(this);
}
DataSet *ds = dataset_edit_dialog->editDataSet();
if(ds) {
selected_dataset = ds;
emit dataSetsChanged();
}
}
void QalculateDataSetsDialog::dataSetDoubleClicked(QListViewItem*i) {
selected_dataset = dataSetItems[i];
if(!selected_dataset)
return;
CHECK_IF_DATASET_STILL_THERE
if(!dataset_edit_dialog) {
dataset_edit_dialog = new QalculateEditDataSetDialog(this);
}
DataSet *ds = dataset_edit_dialog->editDataSet(selected_dataset);
if(ds) {
selected_dataset = ds;
emit dataSetsChanged();
}
}
void QalculateDataSetsDialog::dataSetSelected() {
QListViewItem *selected = dataSetsView->selectedItem();
objectsView->clear();
if(selected) {
DataSet *ds = dataSetItems[selected];
if(!CALCULATOR->stillHasFunction(ds)) {
KMessageBox::error(this, i18n("Data set does not exist anymore."));
selected_dataset = NULL;
emit dataSetsChanged();
return;
}
//remember selection
selected_dataset = ds;
while(objectsView->columns() > 0) {
objectsView->removeColumn(0);
}
DataObjectIter it;
DataPropertyIter pit;
DataProperty *dp;
DataObject *o = ds->getFirstObject(&it);
bool b = false, b2 = false;
QListViewItem *i;
while(o) {
i = new KListViewItem(objectsView);
objectItems[i] = o;
dp = ds->getFirstProperty(&pit);
int index = 0;
while(dp) {
if(!dp->isHidden() && dp->isKey()) {
if(!b2) {
objectsView->addColumn(dp->title().c_str());
}
i->setText(index, o->getPropertyDisplayString(dp).c_str());
index++;
if(index > 2) break;
}
dp = ds->getNextProperty(&pit);
}
b2 = true;
if(o == selected_object) {
objectsView->setSelected(i, true);
b = true;
}
o = ds->getNextObject(&it);
}
if(!b) {
QListViewItemIterator qit(objectsView);
if(qit.current()) {
objectsView->setSelected(qit.current(), true);
}
}
objectsView->sort();
editDataSetButton->setEnabled(true);
deleteDataSetButton->setEnabled(ds->isLocal());
newObjectButton->setEnabled(true);
QString str, str2;
if(!ds->description().empty()) {
str2 = ds->description().c_str();
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
str += "<br><br>";
}
str += "<b>";
str += i18n("Properties");
str += "</b><br>";
dp = ds->getFirstProperty(&pit);
while(dp) {
if(!dp->isHidden()) {
if(!dp->title(false).empty()) {
str2 = dp->title().c_str();
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
str += ": ";
}
for(size_t i = 1; i <= dp->countNames(); i++) {
if(i > 1) str += ", ";
str += dp->getName(i).c_str();
}
if(dp->isKey()) {
str += " (";
//indicating that the property is a data set key
str += i18n("key");
str += ")";
}
str += "<br>";
if(!dp->description().empty()) {
str += "<i>";
str2 = dp->description().c_str();
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
str += "</i><br>";
}
}
dp = ds->getNextProperty(&pit);
}
str += "<br><b>";
str += i18n("Data Retrieval Function");
str += "</b><br>";
Argument *arg;
Argument default_arg;
const ExpressionName *ename = &ds->preferredName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) descriptionBrowser);
str += "<i><b>";
str += ename->name.c_str();
str += "</b>";
int iargs = ds->maxargs();
if(iargs < 0) {
iargs = ds->minargs() + 1;
}
str += "(";
if(iargs != 0) {
for(int i2 = 1; i2 <= iargs; i2++) {
if(i2 > ds->minargs()) {
str += "[";
}
if(i2 > 1) {
str += CALCULATOR->getComma().c_str();
str += " ";
}
arg = ds->getArgumentDefinition(i2);
if(arg && !arg->name().empty()) {
str += arg->name().c_str();
} else {
str += i18n("argument");
str += " ";
str += QString::number(i2);
}
if(i2 > ds->minargs()) {
str += "]";
}
}
if(ds->maxargs() < 0) {
str += CALCULATOR->getComma().c_str();
str += " ...";
}
}
str += ")";
for(size_t i2 = 1; i2 <= ds->countNames(); i2++) {
if(&ds->getName(i2) != ename) {
str += "<br>";
str += ds->getName(i2).name.c_str();
}
}
str += "</i>";
str += "<br>";
if(!ds->copyright().empty()) {
str += "<br>";
str2 = ds->copyright().c_str();
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
str += "<br>";
}
str.replace("\n", "<br>");
descriptionBrowser->setText(str);
} else {
editDataSetButton->setEnabled(false);
deleteDataSetButton->setEnabled(false);
newObjectButton->setEnabled(false);
selected_dataset = NULL;
descriptionBrowser->clear();
}
objectSelected();
}
void QalculateDataSetsDialog::insertObjectData(void *data) {
DataProperty *dp = (DataProperty*) data;
DataSet *ds = dp->parentSet();
if(ds && selected_object) {
QString str = ds->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionWidget).name.c_str();
str += "(";
str += selected_object->getProperty(ds->getPrimaryKeyProperty()).c_str();
str += CALCULATOR->getComma().c_str();
str += " ";
str += dp->getName().c_str();
str += ")";
insert_text_in_expression(str);
}
}
void QalculateDataSetsDialog::objectSelected() {
QListViewItem *selected = objectsView->selectedItem();
DataObject *o = NULL;
if(selected) o = objectItems[selected];
if(o) {
selected_object = o;
editObjectButton->setEnabled(true);
deleteObjectButton->setEnabled(true);
DataSet *ds = o->parentSet();
if(!ds) return;
DataPropertyIter it;
DataProperty *dp = ds->getFirstProperty(&it);
QString sval;
QString str;
delete attributesGrid;
attributesGrid = new QGrid(3, Qt::Horizontal, attributesView->viewport());
attributesGrid->setSpacing(spacingHint());
attributesView->addChild(attributesGrid);
while(dp) {
if(!dp->isHidden()) {
sval = o->getPropertyDisplayString(dp).c_str();
if(!sval.isEmpty()) {
str = "<b>"; str += dp->title().c_str(); str += ":"; str += "</b>";
new QLabel(str, attributesGrid);
KLineEdit *le = new KLineEdit(sval, attributesGrid);
le->setReadOnly(true);
le->setFrameStyle(QFrame::NoFrame | QFrame::Plain);
QalculateButtonWithData *button = new QalculateButtonWithData((void*) dp, QIconSet(SmallIcon("editpaste")), "", attributesGrid);
QObject::connect(button, SIGNAL(clickedWithData(void*)), SLOT(insertObjectData(void*)));
}
}
dp = ds->getNextProperty(&it);
}
QWidget *widget = new QWidget(attributesGrid);
widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding);
attributesGrid->show();
} else {
delete attributesGrid;
attributesGrid = new QGrid(3, Qt::Horizontal, attributesView->viewport());
attributesGrid->setSpacing(spacingHint());
attributesView->addChild(attributesGrid);
attributesGrid->show();
selected_object = NULL;
editObjectButton->setEnabled(false);
deleteObjectButton->setEnabled(false);
}
}
void QalculateDataSetsDialog::deleteObject() {
UPDATE_SELECTED_DATASET
UPDATE_SELECTED_OBJECT
selected_dataset->delObject(selected_object);
selected_object = NULL;
updateObjects();
}
void QalculateDataSetsDialog::updateObjects() {
dataSetSelected();
}
void QalculateDataSetsDialog::editObject() {
UPDATE_SELECTED_DATASET
UPDATE_SELECTED_OBJECT
if(!object_edit_dialog) {
object_edit_dialog = new QalculateEditDataObjectDialog(this);
}
DataObject *o = object_edit_dialog->editDataObject(selected_dataset, selected_object);
if(o) {
selected_object = o;
updateObjects();
}
}
void QalculateDataSetsDialog::newObject() {
UPDATE_SELECTED_DATASET
if(!object_edit_dialog) {
object_edit_dialog = new QalculateEditDataObjectDialog(this);
}
DataObject *o = object_edit_dialog->editDataObject(selected_dataset);
if(o) {
selected_object = o;
updateObjects();
}
}
void QalculateDataSetsDialog::objectDoubleClicked(QListViewItem*i) {
UPDATE_SELECTED_DATASET
selected_object = objectItems[i];
if(!selected_object)
return;
if(!object_edit_dialog) {
object_edit_dialog = new QalculateEditDataObjectDialog(this);
}
DataObject *o = object_edit_dialog->editDataObject(selected_dataset, selected_object);
if(o) {
selected_object = o;
updateObjects();
}
}
#include "qalculatedatasetsdialog.moc"

@ -0,0 +1,85 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEDATASETSDIALOG_H
#define QALCULATEDATASETSDIALOG_H
#include <kdialogbase.h>
#include <qmap.h>
class QPushButton;
class KListView;
class KTextBrowser;
class QScrollView;
class QGrid;
class DataSet;
class DataObject;
class QalculateEditDataSetDialog;
class QalculateEditDataObjectDialog;
/**
@author Niklas Knutsson
*/
class QalculateDataSetsDialog : public KDialogBase {
Q_OBJECT
public:
QalculateDataSetsDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateDataSetsDialog();
QPushButton *newObjectButton, *editObjectButton, *deleteObjectButton, *newDataSetButton, *editDataSetButton, *deleteDataSetButton;
KListView *objectsView, *dataSetsView;
KTextBrowser *descriptionBrowser;
QScrollView *attributesView;
QGrid *attributesGrid;
QMap<QListViewItem*, DataSet*> dataSetItems;
QMap<QListViewItem*, DataObject*> objectItems;
DataSet *selected_dataset;
DataObject *selected_object;
QalculateEditDataSetDialog *dataset_edit_dialog;
QalculateEditDataObjectDialog *object_edit_dialog;
public slots:
void updateDataSetTree();
void dataSetDoubleClicked(QListViewItem*);
void objectDoubleClicked(QListViewItem*);
void dataSetSelected();
void objectSelected();
void deleteDataSet();
void editDataSet();
void newDataSet();
void deleteObject();
void editObject();
void newObject();
void updateObjects();
void insertObjectData(void*);
signals:
void dataSetsChanged();
};
#endif

@ -0,0 +1,55 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculatedecimalsdialog.h"
#include <qlabel.h>
#include <qspinbox.h>
#include <klocale.h>
#include <qgrid.h>
QalculateDecimalsDialog::QalculateDecimalsDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Decimals"), Close, Close, true) {
QGrid *grid = makeGridMainWidget(2, Qt::Horizontal);
new QLabel(i18n("Max decimals:"), grid);
maxDecimalsBox = new QSpinBox(grid);
maxDecimalsBox->setButtonSymbols(QSpinBox::PlusMinus);
maxDecimalsBox->setMinValue(-1);
maxDecimalsBox->setValue(-1);
maxDecimalsBox->setSpecialValueText(i18n( "Off" ));
new QLabel(i18n("Min decimals:"), grid);
minDecimalsBox = new QSpinBox(grid);
minDecimalsBox->setButtonSymbols(QSpinBox::PlusMinus);
minDecimalsBox->setMinValue(0);
minDecimalsBox->setValue(0);
minDecimalsBox->setSpecialValueText(i18n( "Off" ));
resize(QSize(300, minimumSizeHint().height()).expandedTo(minimumSizeHint()));
}
QalculateDecimalsDialog::~QalculateDecimalsDialog() {}
#include "qalculatedecimalsdialog.moc"

@ -0,0 +1,43 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEDECIMALSDIALOG_H
#define QALCULATEDECIMALSDIALOG_H
#include <kdialogbase.h>
class QSpinBox;
/**
@author Niklas Knutsson
*/
class QalculateDecimalsDialog : public KDialogBase {
Q_OBJECT
public:
QalculateDecimalsDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateDecimalsDialog();
QSpinBox *maxDecimalsBox, *minDecimalsBox;
};
#endif

@ -0,0 +1,103 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateeditdataobjectdialog.h"
#include "qalculate_kde_utils.h"
#include <qlabel.h>
#include <qgrid.h>
#include <klineedit.h>
#include <kcombobox.h>
#include <qvaluevector.h>
#include <qstring.h>
#include <klocale.h>
QalculateEditDataObjectDialog::QalculateEditDataObjectDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Object"), Ok | Cancel, Ok, true) {
}
QalculateEditDataObjectDialog::~QalculateEditDataObjectDialog() {}
DataObject *QalculateEditDataObjectDialog::editDataObject(DataSet *ds, DataObject *o) {
if(!ds) return NULL;
if(o) {
setCaption(i18n("Edit Object"));
} else {
setCaption(i18n("New Object"));
}
QGrid *grid = new QGrid(4, Qt::Horizontal, this);
grid->setSpacing(spacingHint());
setMainWidget(grid);
new QLabel(i18n("Property"), grid);
new QLabel(i18n("Value"), grid);
new QLabel(grid);
new QLabel(i18n("Approximation"), grid);
DataPropertyIter it;
DataProperty *dp = ds->getFirstProperty(&it);
string sval;
QValueVector<KLineEdit*> value_entries;
QValueVector<KComboBox*> approx_menus;
string str;
while(dp) {
new QLabel(dp->title().c_str(), grid);
KLineEdit *entry = new KLineEdit(grid);
value_entries.push_back(entry);
int iapprox = -1;
if(o) {
entry->setText(o->getProperty(dp, &iapprox).c_str());
}
new QLabel(dp->getUnitString().c_str(), grid);
KComboBox *om = new KComboBox(grid);
om->setEditable(false);
om->insertItem(i18n("Default"));
om->insertItem(i18n("Approximate"));
om->insertItem(i18n("Exact"));
approx_menus.push_back(om);
om->setCurrentItem(iapprox + 1);
dp = ds->getNextProperty(&it);
}
if(exec() == QDialog::Accepted) {
bool new_object = (o == NULL);
if(new_object) {
o = new DataObject(ds);
ds->addObject(o);
}
dp = ds->getFirstProperty(&it);
size_t i = 0;
QString val;
while(dp) {
val = value_entries[i]->text().stripWhiteSpace();
if(!val.isEmpty()) {
o->setProperty(dp, val.ascii(), approx_menus[i]->currentItem() - 1);
} else if(!new_object) {
o->eraseProperty(dp);
}
dp = ds->getNextProperty(&it);
i++;
}
o->setUserModified();
delete grid;
return o;
}
delete grid;
return NULL;
}
#include "qalculateeditdataobjectdialog.moc"

@ -0,0 +1,44 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEEDITDATAOBJECTDIALOG_H
#define QALCULATEEDITDATAOBJECTDIALOG_H
#include <kdialogbase.h>
class DataObject;
class DataSet;
/**
@author Niklas Knutsson
*/
class QalculateEditDataObjectDialog : public KDialogBase {
Q_OBJECT
public:
QalculateEditDataObjectDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateEditDataObjectDialog();
DataObject *editDataObject(DataSet *ds, DataObject *o = NULL);
};
#endif

@ -0,0 +1,750 @@
/***************************************************************************
* Copyright (C) 2005-2006 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateeditdatasetdialog.h"
#include "qalculate_kde_utils.h"
#include "qalculateeditnamesdialog.h"
#include <qgrid.h>
#include <klineedit.h>
#include <kpushbutton.h>
#include <kcombobox.h>
#include <qlabel.h>
#include <klocale.h>
#include <qvbox.h>
#include <qhbox.h>
#include <qcheckbox.h>
#include <kmessagebox.h>
#include <kdeversion.h>
#include <qlayout.h>
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
#include <qtextedit.h>
#else
#include <ktextedit.h>
#endif
#include <klistview.h>
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
#include <qtabwidget.h>
#else
#include <ktabwidget.h>
#endif
#include <qapplication.h>
#include <kstdguiitem.h>
extern PrintOptions printops;
extern tree_struct function_cats;
QalculateEditDataSetDialog::QalculateEditDataSetDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Data Set"), Ok | Cancel, Ok, false) {
names_edit_dialog = NULL;
edited_dataset = NULL;
property_edit_dialog = NULL;
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
tabs = new QTabWidget(this);
#else
tabs = new KTabWidget(this);
#endif
setMainWidget(tabs);
QWidget *page1 = new QWidget(this);
QWidget *page2 = new QWidget(this);
QWidget *page3 = new QWidget(this);
tabs->addTab(page1, i18n("General"));
tabs->addTab(page2, i18n("Properties"));
tabs->addTab(page3, i18n("Function"));
QGridLayout *grid = new QGridLayout(page1, 1, 1, spacingHint());
grid->addWidget(new QLabel(i18n("Title:"), page1), 0, 0);
titleEdit = new KLineEdit(page1);
grid->addWidget(titleEdit, 0, 1);
grid->addWidget(new QLabel(i18n("Data file:"), page1), 1, 0);
fileEdit = new KLineEdit(page1);
grid->addWidget(fileEdit, 1, 1);
grid->addWidget(new QLabel(i18n("Description:"), page1), 2, 0);
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
descriptionEdit = new QTextEdit(page1);
#else
descriptionEdit = new KTextEdit(page1);
#endif
descriptionEdit->setTextFormat(QTextEdit::PlainText);
grid->addMultiCellWidget(descriptionEdit, 3, 3, 0, 1);
grid->addWidget(new QLabel(i18n("Copyright:"), page1), 4, 0);
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
copyrightEdit = new QTextEdit(page1);
#else
copyrightEdit = new KTextEdit(page1);
#endif
copyrightEdit->setTextFormat(QTextEdit::PlainText);
grid->addMultiCellWidget(copyrightEdit, 5, 5, 0, 1);
QVBoxLayout *vbox = new QVBoxLayout(page2, spacingHint());
vbox->addWidget(new QLabel(i18n("Properties:"), page2));
propertiesView = new KListView(page2);
propertiesView->addColumn(i18n("Title"));
propertiesView->addColumn(i18n("Name"));
propertiesView->addColumn(i18n("Type"));
propertiesView->setSorting(-1);
propertiesView->setRootIsDecorated(false);
vbox->addWidget(propertiesView);
QHBoxLayout *hbox = new QHBoxLayout(vbox, spacingHint());
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
newPropertyButton = new QPushButton(i18n("New"), page2);
hbox->addWidget(newPropertyButton);
editPropertyButton = new QPushButton(i18n("Edit"), page2);
hbox->addWidget(editPropertyButton);
deletePropertyButton = new QPushButton(i18n("Delete"), page2);
hbox->addWidget(deletePropertyButton);
grid = new QGridLayout(page3, 1, 1, spacingHint());
grid->addWidget(new QLabel(i18n("Name:"), page3), 0, 0);
nameEdit = new KLineEdit(page3);
grid->addWidget(nameEdit, 0, 1);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
namesLabel = new QLabel(page3);
namesLabel->setAlignment(Qt::AlignRight);
namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hbox->addWidget(namesLabel);
namesButton = new QPushButton(i18n("Names Details"), page3);
hbox->addWidget(namesButton);
grid->addWidget(new QLabel(i18n("Object argument name:"), page3), 2, 0);
objectArgumentEdit = new KLineEdit(page3);
grid->addWidget(objectArgumentEdit, 2, 1);
grid->addWidget(new QLabel(i18n("Property argument name:"), page3), 3, 0);
propertyArgumentEdit = new KLineEdit(page3);
grid->addWidget(propertyArgumentEdit, 3, 1);
grid->addWidget(new QLabel(i18n("Default property:"), page3), 4, 0);
defaultPropertyEdit = new KLineEdit(page3);
grid->addWidget(defaultPropertyEdit, 4, 1);
grid->addItem(new QSpacerItem(5, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
connect(newPropertyButton, SIGNAL(clicked()), this, SLOT(newProperty()));
connect(editPropertyButton, SIGNAL(clicked()), this, SLOT(editProperty()));
connect(deletePropertyButton, SIGNAL(clicked()), this, SLOT(deleteProperty()));
connect(propertiesView, SIGNAL(selectionChanged()), this, SLOT(propertySelectionChanged()));
}
QalculateEditDataSetDialog::~QalculateEditDataSetDialog() {}
void QalculateEditDataSetDialog::propertySelectionChanged() {
QListViewItem *i = propertiesView->selectedItem();
if(i) {
editPropertyButton->setEnabled(propertiesItems[i]->isUserModified());
deletePropertyButton->setEnabled(propertiesItems[i]->isUserModified());
} else {
editPropertyButton->setEnabled(false);
deletePropertyButton->setEnabled(false);
}
}
void QalculateEditDataSetDialog::updateDatasetPropertyList() {
propertiesView->clear();
propertiesItems.clear();
editPropertyButton->setEnabled(false);
deletePropertyButton->setEnabled(false);
QString str;
QListViewItem *i_prev = NULL;
for(size_t i = 0; i < tmp_props.size(); i++) {
if(tmp_props[i]) {
str = "";
switch(tmp_props[i]->propertyType()) {
case PROPERTY_STRING: {
str += i18n("text");
break;
}
case PROPERTY_NUMBER: {
if(tmp_props[i]->isApproximate()) {
str += i18n("approximate");
str += " ";
}
str += i18n("number");
break;
}
case PROPERTY_EXPRESSION: {
if(tmp_props[i]->isApproximate()) {
str += i18n("approximate");
str += " ";
}
str += i18n("expression");
break;
}
}
if(tmp_props[i]->isKey()) {
str += " (";
str += i18n("key");
str += ")";
}
QListViewItem *item = new KListViewItem(propertiesView, i_prev, tmp_props[i]->title(false).c_str(), tmp_props[i]->getName().c_str(), str);
i_prev = item;
propertiesItems[item] = tmp_props[i];
}
}
}
void QalculateEditDataSetDialog::slotOk() {
string str = nameEdit->text().ascii();
remove_blank_ends(str);
if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
//no name -- open dialog again
tabs->setCurrentPage(2);
nameEdit->setFocus();
KMessageBox::error(this, i18n("Empty name field"));
return;
}
//function with the same name exists -- overwrite or open dialog again
if((!edited_dataset || !edited_dataset->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->functionNameTaken(str, edited_dataset) && KMessageBox::questionYesNo(this, i18n("A function with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
tabs->setCurrentPage(2);
nameEdit->setFocus();
return;
}
DataSet *ds = edited_dataset;
bool add_func = false;
if(ds) {
//edited an existing function
ds->setTitle(titleEdit->text().ascii());
ds->setDescription(descriptionEdit->text().ascii());
if(ds->isLocal()) ds->setDefaultDataFile(fileEdit->text().ascii());
} else {
//new function
ds = new DataSet(i18n("Data Sets").ascii(), "", fileEdit->text().ascii(), titleEdit->text().ascii(), descriptionEdit->text().ascii(), true);
add_func = true;
}
QString str2 = objectArgumentEdit->text().stripWhiteSpace();
if(str2.isEmpty()) str2 = i18n("Object");
Argument *arg = ds->getArgumentDefinition(1);
if(arg) {
arg->setName(str2.ascii());
}
str2 = propertyArgumentEdit->text().stripWhiteSpace();
if(str2.isEmpty()) str2 = i18n("Property");
arg = ds->getArgumentDefinition(2);
if(arg) {
arg->setName(str2.ascii());
}
ds->setDefaultProperty(defaultPropertyEdit->text().ascii());
ds->setCopyright(copyrightEdit->text().ascii());
DataPropertyIter it;
for(size_t i = 0; i < tmp_props.size();) {
if(!tmp_props[i]) {
if(tmp_props_orig[i]) ds->delProperty(tmp_props_orig[i]);
i++;
} else if(tmp_props[i]->isUserModified()) {
if(tmp_props_orig[i]) {
tmp_props_orig[i]->set(*tmp_props[i]);
i++;
} else {
ds->addProperty(tmp_props[i]);
tmp_props.erase(tmp_props.begin() + i);
}
} else {
i++;
}
}
if(names_edit_dialog) {
names_edit_dialog->saveNames(ds, str.c_str());
} else {
if(ds->countNames() == 0) {
ExpressionName ename(str);
ename.reference = true;
ds->setName(ename, 1);
} else {
ds->setName(str, 1);
}
}
if(add_func) {
CALCULATOR->addDataSet(ds);
ds->loadObjects();
ds->setObjectsLoaded(true);
}
for(size_t i = 0; i < tmp_props.size(); i++) {
if(tmp_props[i]) delete tmp_props[i];
}
tmp_props.clear();
tmp_props_orig.clear();
edited_dataset = ds;
accept();
}
DataSet *QalculateEditDataSetDialog::editDataSet(DataSet *ds) {
titleEdit->setFocus();
tabs->setCurrentPage(0);
if(names_edit_dialog) {
delete names_edit_dialog;
names_edit_dialog = NULL;
}
edited_dataset = ds;
if(ds) {
if(ds->isLocal())
setCaption(i18n("Edit Data Set"));
else
setCaption(i18n("Edit Data Set (global)"));
} else {
setCaption(i18n("New Data Set"));
}
//clear entries
fileEdit->setReadOnly(ds && !ds->isLocal());
copyrightEdit->setReadOnly(ds && !ds->isLocal());
nameEdit->clear();
titleEdit->clear();
fileEdit->clear();
objectArgumentEdit->clear();
propertyArgumentEdit->clear();
defaultPropertyEdit->setText(i18n("info"));
namesLabel->clear();
descriptionEdit->clear();
copyrightEdit->clear();
nameEdit->setReadOnly(false);
actionButton(Ok)->setEnabled(true);
newPropertyButton->setEnabled(TRUE);
editPropertyButton->setEnabled(FALSE);
deletePropertyButton->setEnabled(FALSE);
if(ds) {
//fill in original paramaters
set_name_label_and_entry(ds, nameEdit, namesLabel);
fileEdit->setText(ds->defaultDataFile().c_str());
defaultPropertyEdit->setText(ds->defaultProperty().c_str());
titleEdit->setText(ds->title(false).c_str());
Argument *arg = ds->getArgumentDefinition(1);
if(arg) {
objectArgumentEdit->setText(arg->name().c_str());
}
arg = ds->getArgumentDefinition(2);
if(arg) {
propertyArgumentEdit->setText(arg->name().c_str());
}
descriptionEdit->setText(ds->description().c_str());
copyrightEdit->setText(ds->copyright().c_str());
DataPropertyIter it;
DataProperty *dp = ds->getFirstProperty(&it);
while(dp) {
tmp_props.push_back(new DataProperty(*dp));
tmp_props_orig.push_back(dp);
dp = ds->getNextProperty(&it);
}
}
updateDatasetPropertyList();
if(exec() == QDialog::Accepted) {
ds = edited_dataset;
edited_dataset = NULL;
return ds;
}
edited_dataset = NULL;
for(size_t i = 0; i < tmp_props.size(); i++) {
if(tmp_props[i]) delete tmp_props[i];
}
tmp_props.clear();
tmp_props_orig.clear();
return NULL;
}
void QalculateEditDataSetDialog::editNames() {
if(!names_edit_dialog) {
names_edit_dialog = new QalculateEditNamesDialog(TYPE_FUNCTION, this);
names_edit_dialog->setNames(edited_dataset, nameEdit->text(), false);
} else {
names_edit_dialog->setNames(edited_dataset, nameEdit->text(), true);
}
names_edit_dialog->exec();
names_edit_dialog->setNamesLE(nameEdit, namesLabel);
}
void QalculateEditDataSetDialog::newProperty() {
if(!property_edit_dialog) {
property_edit_dialog = new QalculateEditDataPropertyDialog(this);
}
DataProperty *dp = new DataProperty(edited_dataset);
dp->setUserModified(true);
if(property_edit_dialog->editDataProperty(dp, true)) {
tmp_props.push_back(dp);
tmp_props_orig.push_back(NULL);
updateDatasetPropertyList();
} else {
delete dp;
}
}
void QalculateEditDataSetDialog::editProperty() {
QListViewItem *i = propertiesView->selectedItem();
if(i == NULL) return;
if(!property_edit_dialog) {
property_edit_dialog = new QalculateEditDataPropertyDialog(this);
}
if(property_edit_dialog->editDataProperty(propertiesItems[i])) {
updateDatasetPropertyList();
}
}
void QalculateEditDataSetDialog::deleteProperty() {
QListViewItem *i = propertiesView->selectedItem();
if(i == NULL) return;
if(propertiesItems[i]->isUserModified()) {
for(size_t index = 0; index < tmp_props.size(); index++) {
if(tmp_props[index] == propertiesItems[i]) {
if(tmp_props_orig[index]) {
tmp_props[index] = NULL;
} else {
tmp_props.erase(tmp_props.begin() + index);
tmp_props_orig.erase(tmp_props_orig.begin() + index);
}
break;
}
}
updateDatasetPropertyList();
}
}
void QalculateEditDataSetDialog::nameChanged(const QString &name) {
if(name.isNull()) return;
if(!CALCULATOR->functionNameIsValid(name.ascii())) {
nameEdit->blockSignals(true);
nameEdit->setText(CALCULATOR->convertToValidFunctionName(name.ascii()).c_str());
nameEdit->blockSignals(false);
}
}
QalculateEditDataPropertyDialog::QalculateEditDataPropertyDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Property"), Ok | Cancel, Ok, true) {
names_edit_dialog = NULL;
edited_property = NULL;
setMainWidget(new QWidget(this));
QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 0, 0);
nameEdit = new KLineEdit(mainWidget());
grid->addWidget(nameEdit, 0, 1);
QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
namesLabel = new QLabel(mainWidget());
namesLabel->setAlignment(Qt::AlignRight);
namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hbox->addWidget(namesLabel);
namesButton = new QPushButton(i18n("Names Details"), mainWidget());
hbox->addWidget(namesButton);
grid->addWidget(new QLabel(i18n("Descriptive name:"), mainWidget()), 2, 0);
titleEdit = new KLineEdit(mainWidget());
grid->addWidget(titleEdit, 2, 1);
grid->addWidget(new QLabel(i18n("Description:"), mainWidget()), 3, 0);
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
descriptionEdit = new QTextEdit(mainWidget());
#else
descriptionEdit = new KTextEdit(mainWidget());
#endif
descriptionEdit->setTextFormat(QTextEdit::PlainText);
grid->addMultiCellWidget(descriptionEdit, 4, 4, 0, 1);
grid->addWidget(new QLabel(i18n("Value type:"), mainWidget()), 5, 0);
typeCombo = new KComboBox(mainWidget());
typeCombo->setEditable(false);
typeCombo->insertItem(i18n("Text"));
typeCombo->insertItem(i18n("Number"));
typeCombo->insertItem(i18n("Expression"));
grid->addWidget(typeCombo, 5, 1);
hideButton = new QCheckBox(i18n("Hide"), mainWidget());
grid->addWidget(hideButton, 6, 0);
//Use as a unique data set key
keyButton = new QCheckBox(i18n("Use as key"), mainWidget());
grid->addWidget(keyButton, 6, 1);
approximateButton = new QCheckBox(i18n("Approximate value"), mainWidget());
grid->addWidget(approximateButton, 7, 0);
caseButton = new QCheckBox(i18n("Case sensitive value"), mainWidget());
grid->addWidget(caseButton, 7, 1);
bracketsButton = new QCheckBox(i18n("Value uses brackets"), mainWidget());
grid->addWidget(bracketsButton, 8, 0);
grid->addWidget(new QLabel(i18n("Unit expression:"), mainWidget()), 9, 0);
unitEdit = new KLineEdit(mainWidget());
grid->addWidget(unitEdit, 9, 1);
connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
}
QalculateEditDataPropertyDialog::~QalculateEditDataPropertyDialog() {}
void QalculateEditDataPropertyDialog::slotOk() {
string str = nameEdit->text().ascii();
remove_blank_ends(str);
if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
//no name -- open dialog again
nameEdit->setFocus();
KMessageBox::error(this, i18n("Empty name field"));
return;
}
DataProperty *dp = edited_property;
dp->setTitle(titleEdit->text().ascii());
dp->setUnit(unitEdit->text().ascii());
dp->setHidden(hideButton->isChecked());
dp->setKey(keyButton->isChecked());
dp->setApproximate(approximateButton->isChecked());
dp->setCaseSensitive(caseButton->isChecked());
dp->setUsesBrackets(bracketsButton->isChecked());
dp->setDescription(descriptionEdit->text().ascii());
switch(typeCombo->currentItem()) {
case 0: {
dp->setPropertyType(PROPERTY_STRING);
break;
}
case 1: {
dp->setPropertyType(PROPERTY_NUMBER);
break;
}
case 2: {
dp->setPropertyType(PROPERTY_EXPRESSION);
break;
}
}
if(names_edit_dialog) {
names_edit_dialog->saveNames(dp, str.c_str());
} else {
dp->setName(str, 1);
}
edited_property = dp;
accept();
}
bool QalculateEditDataPropertyDialog::editDataProperty(DataProperty *dp, bool newdp) {
nameEdit->setFocus();
if(names_edit_dialog) {
delete names_edit_dialog;
names_edit_dialog = NULL;
}
edited_property = dp;
if(!newdp) {
setCaption(i18n("Edit Property"));
} else {
setCaption(i18n("New Property"));
}
actionButton(Ok)->setEnabled(true);
nameEdit->setText(dp->getName().c_str());
if(dp->countNames() > 1) {
QString str = "+ ";
for(size_t i = 2; i <= dp->countNames(); i++) {
if(i > 2) str += ", ";
str += dp->getName(i).c_str();
}
namesLabel->setText(str);
} else {
namesLabel->clear();
}
titleEdit->setText(dp->title(false).c_str());
unitEdit->setText(dp->getUnitString().c_str());
hideButton->setChecked(dp->isHidden());
keyButton->setChecked(dp->isKey());
approximateButton->setChecked(dp->isApproximate());
caseButton->setChecked(dp->isCaseSensitive());
bracketsButton->setChecked(dp->usesBrackets());
descriptionEdit->setText(dp->description().c_str());
switch(dp->propertyType()) {
case PROPERTY_STRING: {
typeCombo->setCurrentItem(0);
break;
}
case PROPERTY_NUMBER: {
typeCombo->setCurrentItem(1);
break;
}
case PROPERTY_EXPRESSION: {
typeCombo->setCurrentItem(2);
break;
}
}
if(exec() == QDialog::Accepted) {
edited_property = NULL;
return true;
}
edited_property = NULL;
return false;
}
void QalculateEditDataPropertyDialog::editNames() {
if(!names_edit_dialog) {
names_edit_dialog = new QalculateEditDataPropertyNamesDialog(this);
names_edit_dialog->setNames(edited_property, nameEdit->text(), false);
} else {
names_edit_dialog->setNames(edited_property, nameEdit->text(), true);
}
names_edit_dialog->exec();
names_edit_dialog->setNamesLE(nameEdit, namesLabel);
}
QalculateEditDataPropertyNamesDialog::QalculateEditDataPropertyNamesDialog(QWidget *parent, const char *name) : KDialog(parent, name, true) {
setCaption(i18n("Edit Names"));
QVBoxLayout *layout = new QVBoxLayout(this, marginHint(), spacingHint());
namesView = new KListView(this);
namesView->addColumn(i18n("Name"));
namesView->addColumn(i18n("Reference"));
namesView->setColumnAlignment(1, Qt::AlignCenter);
namesView->setSorting(-1);
namesView->setItemsRenameable(true);
namesView->setItemsMovable(true);
layout->addWidget(namesView);
QHBoxLayout *buttonLayout = new QHBoxLayout(layout, spacingHint());
newButton = new QPushButton(i18n("New"), this);
buttonLayout->addWidget(newButton);
deleteButton = new QPushButton(i18n("Delete"), this);
deleteButton->setEnabled(false);
buttonLayout->addWidget(deleteButton);
buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
buttonClose = new KPushButton(KStdGuiItem::close(), this);
buttonClose->setAutoDefault(true);
buttonClose->setDefault(true);
buttonLayout->addWidget(buttonClose);
connect(namesView, SIGNAL(selectionChanged()), this, SLOT(nameSelectionChanged()));
connect(buttonClose, SIGNAL(clicked()), this, SLOT(accept()));
connect(newButton, SIGNAL(clicked()), this, SLOT(newName()));
connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteName()));
connect(namesView, SIGNAL(clicked(QListViewItem*, const QPoint&, int)), this, SLOT(itemClicked(QListViewItem*, const QPoint&, int)));
}
QalculateEditDataPropertyNamesDialog::~QalculateEditDataPropertyNamesDialog() {}
void QalculateEditDataPropertyNamesDialog::newName() {
ExpressionName name;
QListViewItem *i = new KListViewItem(namesView, namesView->lastChild(), "", i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"));
namesView->setSelected(i, true);
qApp->processEvents();
namesView->rename(i, 0);
}
void QalculateEditDataPropertyNamesDialog::setNames(DataProperty *item, const QString &namestr, bool names_edited) {
if(!names_edited) {
deleteButton->setEnabled(false);
namesView->clear();
}
if(!names_edited && item && item->countNames() > 0) {
QListViewItem *i_prev = NULL;
for(size_t index = 1; index <= item->countNames(); index++) {
QListViewItem *i = new KListViewItem(namesView, i_prev);
i_prev = i;
if(item->nameIsReference(index))
i->setText(1, i18n("Yes"));
else
i->setText(1, i18n("No"));
if(index == 1 && !namestr.isEmpty()) {
i->setText(0, namestr);
} else {
i->setText(0, item->getName(index).c_str());
}
}
} else if(!namestr.isEmpty()) {
if(names_edited) {
QListViewItemIterator it(namesView);
if(it.current())
it.current()->setText(0, namestr);
} else {
new KListViewItem(namesView, namestr, i18n("No"));
}
}
}
void QalculateEditDataPropertyNamesDialog::saveNames(DataProperty *item, const QString &str) {
item->clearNames();
QListViewItemIterator it(namesView);
if(it.current()) {
bool b = false;
while(it.current()) {
bool ref = (it.current()->text(1) == i18n("Yes"));
if(b || str.isEmpty())
item->addName(it.current()->text(0).ascii(), ref);
else
item->addName(str.ascii(), ref);
++it;
b = true;
}
} else {
item->addName(str.ascii());
}
}
void QalculateEditDataPropertyNamesDialog::setNamesLE(QLineEdit *entry, QLabel *label) {
int index = 0;
QString str;
QListViewItemIterator it(namesView);
while(it.current()) {
if(index == 0) {
entry->setText(it.current()->text(0));
} else {
if(index == 1) {
str = "+ ";
} else {
str += ", ";
}
str += it.current()->text(0);
}
++it;
index++;
}
label->setText(str);
}
bool QalculateEditDataPropertyNamesDialog::isEmpty() {
return namesView->childCount() <= 0;
}
void QalculateEditDataPropertyNamesDialog::deleteName() {
namesView->removeItem(namesView->selectedItem());
}
void QalculateEditDataPropertyNamesDialog::itemClicked(QListViewItem *i, const QPoint &, int c) {
if(i && c > 0) {
if(i->text(c) == i18n("Yes"))
i->setText(c, i18n("No"));
else
i->setText(c, i18n("Yes"));
}
}
void QalculateEditDataPropertyNamesDialog::nameSelectionChanged() {
deleteButton->setEnabled(namesView->selectedItem() != NULL);
}
#include "qalculateeditdatasetdialog.moc"

@ -0,0 +1,145 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEEDITDATASETDIALOG_H
#define QALCULATEEDITDATASETDIALOG_H
#include <kdialogbase.h>
#include <qmap.h>
#include <qvaluevector.h>
class KLineEdit;
class QCheckBox;
class KComboBox;
class QPushButton;
class MathStructure;
class QalculateEditNamesDialog;
class DataSet;
class KListView;
class QTextEdit;
class DataProperty;
class QTabWidget;
class UserFunction;
class QalculateEditDataPropertyDialog;
class QalculateEditDataPropertyNamesDialog;
class QLineEdit;
/**
@author Niklas Knutsson
*/
class QalculateEditDataSetDialog : public KDialogBase {
Q_OBJECT
public:
QalculateEditDataSetDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateEditDataSetDialog();
DataSet *editDataSet(DataSet *ds = NULL);
void updateDatasetPropertyList();
QalculateEditNamesDialog *names_edit_dialog;
QalculateEditDataPropertyDialog *property_edit_dialog;
DataSet *edited_dataset;
KLineEdit *objectArgumentEdit, *propertyArgumentEdit, *defaultPropertyEdit, *nameEdit, *titleEdit, *fileEdit;
QLabel *namesLabel;
KListView *propertiesView;
QTextEdit *descriptionEdit, *copyrightEdit;
QPushButton *namesButton, *newPropertyButton, *editPropertyButton, *deletePropertyButton;
QTabWidget *tabs;
QMap<QListViewItem*, DataProperty*> propertiesItems;
QValueVector<DataProperty*> tmp_props;
QValueVector<DataProperty*> tmp_props_orig;
public slots:
void propertySelectionChanged();
void editNames();
void newProperty();
void editProperty();
void deleteProperty();
void nameChanged(const QString&);
protected slots:
void slotOk();
};
class QalculateEditDataPropertyDialog : public KDialogBase {
Q_OBJECT
public:
QalculateEditDataPropertyDialog(QWidget *parent = 0, const char *name = 0);
~QalculateEditDataPropertyDialog();
bool editDataProperty(DataProperty *dp, bool newdp = false);
QalculateEditDataPropertyNamesDialog *names_edit_dialog;
DataProperty *edited_property;
KComboBox *typeCombo;
KLineEdit *nameEdit, *titleEdit, *unitEdit;
QLabel *namesLabel;
QCheckBox *hideButton, *keyButton, *approximateButton, *caseButton, *bracketsButton;
QPushButton *namesButton;
QTextEdit *descriptionEdit;
public slots:
void editNames();
protected slots:
void slotOk();
};
class QalculateEditDataPropertyNamesDialog : public KDialog {
Q_OBJECT
public:
QalculateEditDataPropertyNamesDialog(QWidget *parent = 0, const char *name = 0);
~QalculateEditDataPropertyNamesDialog();
void saveNames(DataProperty *item, const QString &str = QString::null);
void setNames(DataProperty *item = NULL, const QString &namestr = QString::null, bool names_edited = false);
bool isEmpty();
void setNamesLE(QLineEdit *entry, QLabel *label);
KListView* namesView;
QPushButton* newButton;
QPushButton* deleteButton;
QPushButton* buttonClose;
int i_type;
public slots:
void itemClicked(QListViewItem*, const QPoint&, int);
void newName();
void deleteName();
void nameSelectionChanged();
};
#endif

@ -0,0 +1,799 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateeditfunctiondialog.h"
#include "qalculate_kde_utils.h"
#include "qalculateeditnamesdialog.h"
#include <qgrid.h>
#include <klineedit.h>
#include <kpushbutton.h>
#include <kcombobox.h>
#include <qlabel.h>
#include <klocale.h>
#include <qvbox.h>
#include <qhbox.h>
#include <qcheckbox.h>
#include <kmessagebox.h>
#include <qlayout.h>
#include <kdeversion.h>
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
#include <qtextedit.h>
#else
#include <ktextedit.h>
#endif
#include <klistview.h>
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
#include <qtabwidget.h>
#else
#include <ktabwidget.h>
#endif
#include <qheader.h>
#include <kapplication.h>
#include <kstdguiitem.h>
extern PrintOptions printops;
extern EvaluationOptions evalops;
extern tree_struct function_cats;
QalculateEditFunctionDialog::QalculateEditFunctionDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Function"), Ok | Cancel | Help, Ok, false) {
names_edit_dialog = NULL;
subfunctions_edit_dialog = NULL;
edited_function = NULL;
argument_edit_dialog = NULL;
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
tabs = new QTabWidget(this);
#else
tabs = new KTabWidget(this);
#endif
setMainWidget(tabs);
QWidget *page1 = new QWidget(this);
QWidget *page2 = new QWidget(this);
tabs->addTab(page1, i18n("General"));
tabs->addTab(page2, i18n("Function"));
QGridLayout *grid = new QGridLayout(page1, 1, 1, spacingHint());
QVBoxLayout *vbox = new QVBoxLayout(page2, spacingHint());
grid->addWidget(new QLabel(i18n("Name:"), page1), 0, 0);
nameEdit = new KLineEdit(page1);
grid->addWidget(nameEdit, 0, 1);
QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
namesLabel = new QLabel(page1);
namesLabel->setAlignment(Qt::AlignRight);
namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hbox->addWidget(namesLabel);
namesButton = new QPushButton(i18n("Names Details"), page1);
hbox->addWidget(namesButton);
grid->addWidget(new QLabel(i18n("Category:"), page1), 2, 0);
categoryCombo = new KComboBox(page1);
categoryCombo->setMaximumWidth(250);
categoryCombo->setEditable(true);
grid->addWidget(categoryCombo, 2, 1);
grid->addWidget(new QLabel(i18n("Descriptive name:"), page1), 3, 0);
titleEdit = new KLineEdit(page1);
grid->addWidget(titleEdit, 3, 1);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 4, 4, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
hideButton = new QCheckBox(i18n("Hide function"), page1);
hbox->addWidget(hideButton);
grid->addWidget(new QLabel(i18n("Description:"), page1), 5, 0);
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
descriptionEdit = new QTextEdit(page1);
#else
descriptionEdit = new KTextEdit(page1);
#endif
descriptionEdit->setTextFormat(QTextEdit::PlainText);
grid->addMultiCellWidget(descriptionEdit, 6, 6, 0, 1);
vbox->addWidget(new QLabel(i18n("Expression:"), page2));
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1
expressionEdit = new QTextEdit(page2);
#else
expressionEdit = new KTextEdit(page2);
#endif
expressionEdit->setTextFormat(QTextEdit::PlainText);
vbox->addWidget(expressionEdit);
hbox = new QHBoxLayout(vbox, spacingHint());
hbox->addWidget(new QLabel(i18n("Condition:"), page2));
conditionEdit = new KLineEdit(page2);
hbox->addWidget(conditionEdit);
hbox = new QHBoxLayout(vbox, spacingHint());
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
subFunctionsButton = new QPushButton(i18n("Sub-Functions"), page2);
hbox->addWidget(subFunctionsButton);
vbox->addWidget(new QLabel(i18n("Arguments:"), page2));
argumentsView = new KListView(page2);
argumentsView->addColumn(i18n("Name"));
argumentsView->addColumn(i18n("Type"));
argumentsView->setSorting(-1);
argumentsView->setRootIsDecorated(false);
argumentsView->setItemsRenameable(true);
argumentsView->setItemsMovable(false);
vbox->addWidget(argumentsView);
hbox = new QHBoxLayout(vbox, spacingHint());
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
newArgumentButton = new QPushButton(i18n("New"), page2);
hbox->addWidget(newArgumentButton);
editArgumentButton = new QPushButton(i18n("Edit"), page2);
hbox->addWidget(editArgumentButton);
deleteArgumentButton = new QPushButton(i18n("Delete"), page2);
hbox->addWidget(deleteArgumentButton);
connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
connect(subFunctionsButton, SIGNAL(clicked()), this, SLOT(editSubFunctions()));
connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
connect(newArgumentButton, SIGNAL(clicked()), this, SLOT(newArgument()));
connect(editArgumentButton, SIGNAL(clicked()), this, SLOT(editArgument()));
connect(deleteArgumentButton, SIGNAL(clicked()), this, SLOT(deleteArgument()));
connect(argumentsView, SIGNAL(itemRenamed(QListViewItem*, const QString&, int)), this, SLOT(argumentRenamed(QListViewItem*, const QString&, int)));
connect(argumentsView, SIGNAL(selectionChanged()), this, SLOT(argumentSelectionChanged()));
}
QalculateEditFunctionDialog::~QalculateEditFunctionDialog() {}
void QalculateEditFunctionDialog::slotHelp() {
KApplication::kApplication()->invokeHelp("qalculate-function-creation");
}
void QalculateEditFunctionDialog::argumentSelectionChanged() {
QListViewItem *i = argumentsView->selectedItem();
if(i == NULL || (edited_function && edited_function->isBuiltin()) || argumentsItems[i]->type() > ARGUMENT_TYPE_ANGLE) {
editArgumentButton->setEnabled(false);
deleteArgumentButton->setEnabled(false);
} else {
editArgumentButton->setEnabled(true);
deleteArgumentButton->setEnabled(true);
}
}
void QalculateEditFunctionDialog::argumentRenamed(QListViewItem *i, const QString &str, int col) {
if(!i || col != 0) return;
if(col == 0) {
if(!argumentsItemsEdited[i]) {
argumentsItems[i] = argumentsItems[i]->copy();
argumentsItemsEdited[i] = true;
}
argumentsItems[i]->setName(str.ascii());
}
}
void QalculateEditFunctionDialog::slotOk() {
string str = nameEdit->text().ascii();
remove_blank_ends(str);
string str2 = CALCULATOR->unlocalizeExpression(expressionEdit->text().ascii(), evalops.parse_options);
remove_blank_ends(str2);
gsub("\n", " ", str2);
if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
//no name -- open dialog again
tabs->setCurrentPage(0);
nameEdit->setFocus();
KMessageBox::error(this, i18n("Empty name field"));
return;
}
if(!(edited_function && edited_function->isBuiltin()) && str2.empty()) {
//no expression/relation -- open dialog again
tabs->setCurrentPage(1);
expressionEdit->setFocus();
KMessageBox::error(this, i18n("Empty expression field"));
return;
}
//function with the same name exists -- overwrite or open dialog again
if((!edited_function || !edited_function->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->functionNameTaken(str, edited_function) && KMessageBox::questionYesNo(this, i18n("A function with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
tabs->setCurrentPage(0);
nameEdit->setFocus();
return;
}
MathFunction *f = edited_function;
bool add_func = false;
if(f) {
f->setLocal(true);
//edited an existing function
f->setCategory(categoryCombo->lineEdit()->text().ascii());
f->setTitle(titleEdit->text().ascii());
f->setDescription(descriptionEdit->text().ascii());
} else {
//new function
f = new UserFunction(categoryCombo->lineEdit()->text().ascii(), "", "", true, -1, titleEdit->text().ascii(), descriptionEdit->text().ascii());
add_func = true;
}
f->setCondition(CALCULATOR->unlocalizeExpression(conditionEdit->text().ascii(), evalops.parse_options));
size_t index = 1;
QListViewItemIterator it(argumentsView);
while(it.current()) {
if(argumentsItemsEdited[it.current()]) {
if(f->isBuiltin() && f->getArgumentDefinition(index)) {
f->getArgumentDefinition(index)->setName(argumentsItems[it.current()]->name());
delete argumentsItems[it.current()];
} else {
f->setArgumentDefinition(index, argumentsItems[it.current()]);
}
}
++it;
index++;
}
if(!f->isBuiltin()) {
for(; index <= f->lastArgumentDefinitionIndex(); index++) {
f->setArgumentDefinition(index, NULL);
}
}
argumentsItemsEdited.clear();
argumentsItems.clear();
f->setHidden(hideButton->isChecked());
if(!f->isBuiltin()) {
if(names_edit_dialog) {
names_edit_dialog->saveNames(f, str.c_str());
} else {
if(f->countNames() == 0) {
ExpressionName ename(str);
ename.reference = true;
f->setName(ename, 1);
} else {
f->setName(str, 1);
}
}
if(subfunctions_edit_dialog) {
subfunctions_edit_dialog->saveSubFunctions((UserFunction*) f);
}
((UserFunction*) f)->setFormula(str2);
}
if(add_func) {
CALCULATOR->addFunction(f);
}
edited_function = f;
accept();
}
MathFunction *QalculateEditFunctionDialog::editFunction(QString category, MathFunction *f) {
nameEdit->setFocus();
tabs->setCurrentPage(0);
if(names_edit_dialog) {
delete names_edit_dialog;
names_edit_dialog = NULL;
}
if(subfunctions_edit_dialog) {
delete subfunctions_edit_dialog;
subfunctions_edit_dialog = NULL;
}
edited_function = f;
if(f) {
if(f->isLocal())
setCaption(i18n("Edit Function"));
else
setCaption(i18n("Edit Function (global)"));
} else {
setCaption(i18n("New Function"));
}
QString catstr;
categoryCombo->clear();
tree_struct *item, *item2;
function_cats.it = function_cats.items.begin();
if(function_cats.it != function_cats.items.end()) {
item = &*function_cats.it;
++function_cats.it;
item->it = item->items.begin();
} else {
item = NULL;
}
catstr = "";
while(item) {
if(!catstr.isEmpty()) catstr += "/";
catstr += item->item.c_str();
categoryCombo->insertItem(catstr);
while(item && item->it == item->items.end()) {
int str_i = catstr.findRev("/");
if(str_i < 0) {
catstr = "";
} else {
catstr.truncate(str_i);
}
item = item->parent;
}
if(item) {
item2 = &*item->it;
++item->it;
item = item2;
item->it = item->items.begin();
}
}
//clear entries
nameEdit->clear();
namesLabel->clear();
conditionEdit->clear();
nameEdit->setReadOnly(f && f->isBuiltin());
expressionEdit->setEnabled(!f || !f->isBuiltin());
categoryCombo->lineEdit()->setText(category);
titleEdit->clear();
descriptionEdit->clear();
expressionEdit->clear();
hideButton->setChecked(false);
actionButton(Ok)->setEnabled(true);
subFunctionsButton->setEnabled(!f || !f->isBuiltin());
conditionEdit->setReadOnly(f && f->isBuiltin());
newArgumentButton->setEnabled(!f || !f->isBuiltin());
if(f) {
//fill in original paramaters
set_name_label_and_entry(f, nameEdit, namesLabel);
if(!f->isBuiltin()) {
expressionEdit->setText(CALCULATOR->localizeExpression(((UserFunction*) f)->formula()).c_str());
}
categoryCombo->lineEdit()->setText(f->category().c_str());
titleEdit->setText(f->title(false).c_str());
conditionEdit->setText(CALCULATOR->localizeExpression(f->condition()).c_str());
hideButton->setChecked(f->isHidden());
descriptionEdit->setText(f->description().c_str());
}
argumentsView->clear();
argumentsItems.clear();
argumentsItemsEdited.clear();
editArgumentButton->setEnabled(false);
deleteArgumentButton->setEnabled(false);
Argument defarg;
if(f) {
Argument *arg;
int args = f->maxargs();
if(args < 0) {
args = f->minargs() + 1;
}
QString str, str2;
QListViewItem *i_prev = NULL;
for(int i = 1; i <= args; i++) {
arg = f->getArgumentDefinition(i);
if(arg) {
arg = arg->copy();
str = arg->printlong().c_str();
str2 = arg->name().c_str();
} else {
arg = &defarg;
str = defarg.printlong().c_str();
str2 = "";
}
QListViewItem *i = new KListViewItem(argumentsView, i_prev, str2, str);
i_prev = i;
argumentsItems[i] = arg;
argumentsItemsEdited[i] = false;
}
}
argumentsView->setResizeMode(KListView::AllColumns);
if(exec() == QDialog::Accepted) {
f = edited_function;
edited_function = NULL;
return f;
}
QListViewItemIterator it(argumentsView);
while(it.current()) {
if(argumentsItemsEdited[it.current()]) {
delete argumentsItems[it.current()];
}
++it;
}
argumentsItemsEdited.clear();
argumentsItems.clear();
edited_function = NULL;
return NULL;
}
void QalculateEditFunctionDialog::editNames() {
if(!names_edit_dialog) {
names_edit_dialog = new QalculateEditNamesDialog(TYPE_FUNCTION, this);
names_edit_dialog->setNames(edited_function, nameEdit->text(), false);
} else {
names_edit_dialog->setNames(edited_function, nameEdit->text(), true);
}
names_edit_dialog->exec();
names_edit_dialog->setNamesLE(nameEdit, namesLabel);
}
void QalculateEditFunctionDialog::newArgument() {
if(!argument_edit_dialog) {
argument_edit_dialog = new QalculateEditArgumentDialog(this);
}
Argument *arg = argument_edit_dialog->editArgument();
if(arg) {
QListViewItem *i = new KListViewItem(argumentsView, argumentsView->lastChild(), arg->name().c_str(), arg->printlong().c_str());
argumentsItems[i] = arg;
argumentsItemsEdited[i] = true;
}
}
void QalculateEditFunctionDialog::editArgument() {
QListViewItem *i = argumentsView->selectedItem();
if(i == NULL) return;
if(!argument_edit_dialog) {
argument_edit_dialog = new QalculateEditArgumentDialog(this);
}
Argument *arg = argument_edit_dialog->editArgument(argumentsItems[i]);
if(arg) {
if(argumentsItemsEdited[i]) {
delete argumentsItems[i];
}
argumentsItemsEdited[i] = true;
argumentsItems[i] = arg;
i->setText(0, arg->name().c_str());
i->setText(1, arg->printlong().c_str());
}
}
void QalculateEditFunctionDialog::deleteArgument() {
QListViewItem *i = argumentsView->selectedItem();
if(i == NULL) return;
if(argumentsItemsEdited[i]) {
delete argumentsItems[i];
}
argumentsItemsEdited.erase(i);
argumentsItems.erase(i);
argumentsView->removeItem(i);
}
void QalculateEditFunctionDialog::editSubFunctions() {
if(edited_function && edited_function->isBuiltin()) return;
if(!subfunctions_edit_dialog) {
subfunctions_edit_dialog = new QalculateEditSubFunctionsDialog(this);
subfunctions_edit_dialog->setSubFunctions((UserFunction*) edited_function, false);
} else {
subfunctions_edit_dialog->setSubFunctions((UserFunction*) edited_function, true);
}
subfunctions_edit_dialog->exec();
}
void QalculateEditFunctionDialog::nameChanged(const QString &name) {
if(name.isNull()) return;
if(!CALCULATOR->functionNameIsValid(name.ascii())) {
nameEdit->blockSignals(true);
nameEdit->setText(CALCULATOR->convertToValidFunctionName(name.ascii()).c_str());
nameEdit->blockSignals(false);
}
}
QalculateEditSubFunctionsDialog::QalculateEditSubFunctionsDialog(QWidget *parent, const char *name) : KDialog(parent, name, true) {
setCaption(i18n("Sub-Functions"));
QVBoxLayout *layout = new QVBoxLayout(this, marginHint(), spacingHint());
subFunctionsView = new KListView(this);
subFunctionsView->addColumn(i18n("Reference"));
subFunctionsView->addColumn(i18n("Expression"));
subFunctionsView->addColumn(i18n("Precalculate"));
subFunctionsView->setSorting(-1);
subFunctionsView->setItemsRenameable(true);
subFunctionsView->setRenameable(0, false);
subFunctionsView->setRenameable(1, true);
subFunctionsView->setItemsMovable(false);
layout->addWidget(subFunctionsView);
QHBoxLayout *buttonLayout = new QHBoxLayout(layout, spacingHint());
newButton = new QPushButton(i18n("New"), this);
buttonLayout->addWidget(newButton);
deleteButton = new QPushButton(i18n("Delete"), this);
deleteButton->setEnabled(false);
buttonLayout->addWidget(deleteButton);
buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
buttonClose = new KPushButton(KStdGuiItem::close(), this);
buttonClose->setAutoDefault(true);
buttonClose->setDefault(true);
buttonLayout->addWidget(buttonClose);
connect(subFunctionsView, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
connect(buttonClose, SIGNAL(clicked()), this, SLOT(accept()));
connect(newButton, SIGNAL(clicked()), this, SLOT(newSubFunction()));
connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteSubFunction()));
connect(subFunctionsView, SIGNAL(clicked(QListViewItem*, const QPoint&, int)), this, SLOT(itemClicked(QListViewItem*, const QPoint&, int)));
}
QalculateEditSubFunctionsDialog::~QalculateEditSubFunctionsDialog() {}
void QalculateEditSubFunctionsDialog::newSubFunction() {
ExpressionName name;
QString str = "\\";
str += QString::number(subFunctionsView->childCount() + 1);
QListViewItem *i = new KListViewItem(subFunctionsView, subFunctionsView->lastChild(), str, "", i18n("Yes"));
subFunctionsView->setSelected(i, true);
qApp->processEvents();
subFunctionsView->rename(i, 1);
}
void QalculateEditSubFunctionsDialog::setSubFunctions(UserFunction *f, bool edited) {
if(!edited) {
deleteButton->setEnabled(false);
subFunctionsView->clear();
}
if(!edited && f && f->countSubfunctions() > 0) {
QListViewItem *i_prev = NULL;
for(size_t index = 1; index <= f->countSubfunctions(); index++) {
QListViewItem *i = new KListViewItem(subFunctionsView, i_prev);
i_prev = i;
QString str = "\\";
str += QString::number(index);
i->setText(0, str);
i->setText(1, f->getSubfunction(index).c_str());
if(f->subfunctionPrecalculated(index)) i->setText(2, i18n("Yes"));
else i->setText(2, i18n("No"));
}
}
}
void QalculateEditSubFunctionsDialog::saveSubFunctions(UserFunction *f) {
f->clearSubfunctions();
QListViewItemIterator it(subFunctionsView);
while(it.current()) {
f->addSubfunction(it.current()->text(1).ascii(), it.current()->text(2) == i18n("Yes"));
++it;
}
}
bool QalculateEditSubFunctionsDialog::isEmpty() {
return subFunctionsView->childCount() <= 0;
}
void QalculateEditSubFunctionsDialog::deleteSubFunction() {
subFunctionsView->removeItem(subFunctionsView->selectedItem());
QListViewItemIterator it(subFunctionsView);
int index = 1;
while(it.current()) {
QString str = "\\";
str += QString::number(index);
it.current()->setText(0, str);
++it;
index++;
}
}
void QalculateEditSubFunctionsDialog::itemClicked(QListViewItem *i, const QPoint &, int c) {
if(i && c == 2) {
if(i->text(c) == i18n("Yes"))
i->setText(c, i18n("No"));
else
i->setText(c, i18n("Yes"));
}
}
void QalculateEditSubFunctionsDialog::selectionChanged() {
deleteButton->setEnabled(subFunctionsView->selectedItem() != NULL);
}
QalculateEditArgumentDialog::QalculateEditArgumentDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Argument"), Ok | Cancel, Ok, true) {
setMainWidget(new QWidget(this));
QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 0, 0);
nameEdit = new KLineEdit(mainWidget());
grid->addWidget(nameEdit, 0, 1);
grid->addWidget(new QLabel(i18n("Type:"), mainWidget()), 1, 0);
typeCombo = new KComboBox(mainWidget());
typeCombo->setEditable(false);
typeCombo->insertItem(i18n("Free"));
typeCombo->insertItem(i18n("Number"));
typeCombo->insertItem(i18n("Integer"));
typeCombo->insertItem(i18n("Symbol"));
typeCombo->insertItem(i18n("Text"));
typeCombo->insertItem(i18n("Date"));
typeCombo->insertItem(i18n("Vector"));
typeCombo->insertItem(i18n("Matrix"));
typeCombo->insertItem(i18n("Boolean"));
typeCombo->insertItem(i18n("Object"));
typeCombo->insertItem(i18n("Function"));
typeCombo->insertItem(i18n("Unit"));
typeCombo->insertItem(i18n("Variable"));
typeCombo->insertItem(i18n("File"));
typeCombo->insertItem(i18n("Angle"));
grid->addWidget(typeCombo, 1, 1);
testButton = new QCheckBox(i18n("Enable rules and type test"), mainWidget());
grid->addMultiCellWidget(testButton, 2, 2, 0, 1);
conditionButton = new QCheckBox(i18n("Custom condition:"), mainWidget());
grid->addWidget(conditionButton, 3, 0);
conditionEdit = new KLineEdit(mainWidget());
grid->addWidget(conditionEdit, 3, 1);
matrixButton = new QCheckBox(i18n("Allow matrix"), mainWidget());
grid->addMultiCellWidget(matrixButton, 4, 4, 0, 1);
zeroButton = new QCheckBox(i18n("Forbid zero"), mainWidget());
grid->addMultiCellWidget(zeroButton, 5, 5, 0, 1);
complexButton = new QCheckBox(i18n("Allow complex"), mainWidget());
grid->addMultiCellWidget(complexButton, 6, 6, 0, 1);
minButton = new QCheckBox(i18n("Min:"), mainWidget());
grid->addWidget(minButton, 7, 0);
minEdit = new KLineEdit(mainWidget());
grid->addWidget(minEdit, 7, 1);
QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 8, 8, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
minIncludeEqualsButton = new QCheckBox(i18n("Include equals"), mainWidget());
hbox->addWidget(minIncludeEqualsButton);
maxButton = new QCheckBox(i18n("Max:"), mainWidget());
grid->addWidget(maxButton, 9, 0);
maxEdit = new KLineEdit(mainWidget());
grid->addWidget(maxEdit, 9, 1);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 10, 10, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
maxIncludeEqualsButton = new QCheckBox(i18n("Include equals"), mainWidget());
hbox->addWidget(maxIncludeEqualsButton);
connect(conditionButton, SIGNAL(toggled(bool)), conditionEdit, SLOT(setEnabled(bool)));
connect(minButton, SIGNAL(toggled(bool)), this, SLOT(minEnabled(bool)));
connect(maxButton, SIGNAL(toggled(bool)), this, SLOT(maxEnabled(bool)));
connect(typeCombo, SIGNAL(activated(int)), this, SLOT(typeChanged(int)));
}
QalculateEditArgumentDialog::~QalculateEditArgumentDialog() {}
void QalculateEditArgumentDialog::typeChanged(int i) {
maxButton->setEnabled(i == 1 || i == 2);
maxEdit->setEnabled(maxButton->isChecked() && (i == 1 || i == 2));
maxIncludeEqualsButton->setEnabled(maxButton->isChecked() && i == 1);
maxIncludeEqualsButton->setChecked(i == 1 || i == 2);
minButton->setEnabled(i == 1 || i == 2);
minEdit->setEnabled(maxButton->isChecked() && (i == 1 || i == 2));
minIncludeEqualsButton->setEnabled(minButton->isChecked() && i == 1);
minIncludeEqualsButton->setChecked(i == 1 || i == 2);
matrixButton->setEnabled(i != 7 && i != 0);
matrixButton->setChecked(i == 7 || i == 0);
complexButton->setEnabled(i == 1);
complexButton->setChecked(i == 1);
}
void QalculateEditArgumentDialog::maxEnabled(bool b) {
maxEdit->setEnabled(b);
if(typeCombo->currentItem() == 2) {
maxIncludeEqualsButton->setEnabled(b);
}
}
void QalculateEditArgumentDialog::minEnabled(bool b) {
minEdit->setEnabled(b);
if(typeCombo->currentItem() == 2) {
minIncludeEqualsButton->setEnabled(b);
}
}
Argument *QalculateEditArgumentDialog::editArgument(Argument *arg) {
if(arg) {
setCaption(i18n("Edit Argument"));
} else {
setCaption(i18n("New Argument"));
}
nameEdit->setFocus();
typeCombo->setCurrentItem(0);
conditionEdit->clear();
conditionButton->setChecked(false);
nameEdit->clear();
maxEdit->setText("0");
minEdit->setText("0");
testButton->setChecked(true);
zeroButton->setChecked(false);
matrixButton->setChecked(false);
complexButton->setChecked(false);
PrintOptions po;
po.number_fraction_format = FRACTION_DECIMAL_EXACT;
if(arg) {
switch(arg->type()) {
case ARGUMENT_TYPE_NUMBER: {
typeCombo->setCurrentItem(1);
NumberArgument *farg = (NumberArgument*) arg;
minButton->setChecked(farg->min() != NULL);
minIncludeEqualsButton->setChecked(farg->includeEqualsMin());
if(farg->min()) minEdit->setText(farg->min()->print(po).c_str());
maxButton->setChecked(farg->max() != NULL);
maxIncludeEqualsButton->setChecked(farg->includeEqualsMax());
if(farg->max()) maxEdit->setText(farg->max()->print(po).c_str());
complexButton->setChecked(farg->complexAllowed());
break;
}
case ARGUMENT_TYPE_INTEGER: {
typeCombo->setCurrentItem(2);
IntegerArgument *iarg = (IntegerArgument*) arg;
minButton->setChecked(iarg->min() != NULL);
if(iarg->min()) minEdit->setText(iarg->min()->print(po).c_str());
maxButton->setChecked(iarg->max() != NULL);
if(iarg->max()) maxEdit->setText(iarg->max()->print(po).c_str());
break;
}
case ARGUMENT_TYPE_TEXT: {typeCombo->setCurrentItem(4); break;}
case ARGUMENT_TYPE_SYMBOLIC: {typeCombo->setCurrentItem(3); break;}
case ARGUMENT_TYPE_DATE: {typeCombo->setCurrentItem(5); break;}
case ARGUMENT_TYPE_VECTOR: {typeCombo->setCurrentItem(6); break;}
case ARGUMENT_TYPE_MATRIX: {typeCombo->setCurrentItem(7); break;}
case ARGUMENT_TYPE_EXPRESSION_ITEM: {typeCombo->setCurrentItem(9); break;}
case ARGUMENT_TYPE_FUNCTION: {typeCombo->setCurrentItem(10); break;}
case ARGUMENT_TYPE_UNIT: {typeCombo->setCurrentItem(11); break;}
case ARGUMENT_TYPE_VARIABLE: {typeCombo->setCurrentItem(12); break;}
case ARGUMENT_TYPE_FILE: {typeCombo->setCurrentItem(13); break;}
case ARGUMENT_TYPE_BOOLEAN: {typeCombo->setCurrentItem(8); break;}
case ARGUMENT_TYPE_ANGLE: {typeCombo->setCurrentItem(14); break;}
}
nameEdit->setText(arg->name().c_str());
matrixButton->setChecked(arg->matrixAllowed());
zeroButton->setChecked(arg->zeroForbidden());
testButton->setChecked(arg->tests());
if(!arg->getCustomCondition().empty()) {
conditionButton->setChecked(true);
conditionEdit->setText(arg->getCustomCondition().c_str());
}
}
typeChanged(typeCombo->currentItem());
if(exec() == QDialog::Accepted) {
switch(typeCombo->currentItem()) {
case 1: {
arg = new NumberArgument();
if(minButton->isChecked()) {
Number nr(minEdit->text().ascii());
((NumberArgument*) arg)->setMin(&nr);
}
((NumberArgument*) arg)->setIncludeEqualsMin(minIncludeEqualsButton->isChecked());
if(maxButton->isChecked()) {
Number nr(maxEdit->text().ascii());
((NumberArgument*) arg)->setMax(&nr);
}
((NumberArgument*) arg)->setIncludeEqualsMax(maxIncludeEqualsButton->isChecked());
break;
}
case 2: {
arg = new IntegerArgument();
if(minButton->isChecked()) {
Number nr(minEdit->text().ascii());
((IntegerArgument*) arg)->setMin(&nr);
}
if(maxButton->isChecked()) {
Number nr(maxEdit->text().ascii());
((IntegerArgument*) arg)->setMax(&nr);
}
break;
}
case 3: {arg = new SymbolicArgument(); break;}
case 4: {arg = new TextArgument(); break;}
case 5: {arg = new DateArgument(); break;}
case 6: {arg = new VectorArgument(); break;}
case 7: {arg = new MatrixArgument(); break;}
case 8: {arg = new BooleanArgument(); break;}
case 9: {arg = new ExpressionItemArgument(); break;}
case 10: {arg = new FunctionArgument(); break;}
case 11: {arg = new UnitArgument(); break;}
case 12: {arg = new VariableArgument(); break;}
case 13: {arg = new FileArgument(); break;}
case 14: {arg = new AngleArgument(); break;}
default: {arg = new Argument(); break;}
}
arg->setName(nameEdit->text().ascii());
arg->setZeroForbidden(zeroButton->isChecked());
arg->setTests(testButton->isChecked());
if(conditionButton->isChecked()) {
arg->setCustomCondition(conditionEdit->text().ascii());
} else {
arg->setCustomCondition("");
}
if(arg->type() != ARGUMENT_TYPE_FREE && arg->type() != ARGUMENT_TYPE_MATRIX) arg->setMatrixAllowed(matrixButton->isChecked());
return arg;
}
return NULL;
}
#include "qalculateeditfunctiondialog.moc"

@ -0,0 +1,140 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEEDITFUNCTIONDIALOG_H
#define QALCULATEEDITFUNCTIONDIALOG_H
#include <kdialogbase.h>
#include <qmap.h>
class QLabel;
class KComboBox;
class KLineEdit;
class QCheckBox;
class QPushButton;
class MathStructure;
class QalculateEditNamesDialog;
class QalculateEditSubFunctionsDialog;
class QalculateEditArgumentDialog;
class MathFunction;
class KListView;
class QTextEdit;
class Argument;
class QTabWidget;
class UserFunction;
/**
@author Niklas Knutsson
*/
class QalculateEditFunctionDialog : public KDialogBase {
Q_OBJECT
public:
QalculateEditFunctionDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateEditFunctionDialog();
MathFunction *editFunction(QString category = QString::null, MathFunction *f = NULL);
QalculateEditNamesDialog *names_edit_dialog;
QalculateEditSubFunctionsDialog *subfunctions_edit_dialog;
QalculateEditArgumentDialog *argument_edit_dialog;
MathFunction *edited_function;
KComboBox *categoryCombo;
KLineEdit *conditionEdit, *nameEdit, *titleEdit;
QLabel *namesLabel;
QCheckBox *hideButton;
KListView *argumentsView;
QTextEdit *descriptionEdit, *expressionEdit;
QPushButton *namesButton, *subFunctionsButton, *newArgumentButton, *editArgumentButton, *deleteArgumentButton;
QTabWidget *tabs;
QMap<QListViewItem*, Argument*> argumentsItems;
QMap<QListViewItem*, bool> argumentsItemsEdited;
public slots:
void argumentSelectionChanged();
void argumentRenamed(QListViewItem*, const QString&, int);
void editNames();
void newArgument();
void editArgument();
void deleteArgument();
void editSubFunctions();
void nameChanged(const QString&);
protected slots:
void slotHelp();
void slotOk();
};
class QalculateEditSubFunctionsDialog : public KDialog {
Q_OBJECT
public:
QalculateEditSubFunctionsDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateEditSubFunctionsDialog();
void saveSubFunctions(UserFunction *f);
void setSubFunctions(UserFunction *f = NULL, bool edited = false);
bool isEmpty();
KListView* subFunctionsView;
QPushButton* newButton;
QPushButton* deleteButton;
QPushButton* buttonClose;
public slots:
void itemClicked(QListViewItem*, const QPoint&, int);
void newSubFunction();
void deleteSubFunction();
void selectionChanged();
};
class QalculateEditArgumentDialog : public KDialogBase {
Q_OBJECT
public:
QalculateEditArgumentDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateEditArgumentDialog();
Argument *editArgument(Argument *arg = NULL);
KComboBox *typeCombo;
KLineEdit *nameEdit, *conditionEdit, *maxEdit, *minEdit;
QCheckBox *conditionButton, *matrixButton, *zeroButton, *complexButton, *maxButton, *minButton, *maxIncludeEqualsButton, *minIncludeEqualsButton, *testButton;
public slots:
void maxEnabled(bool);
void minEnabled(bool);
void typeChanged(int);
};
#endif

@ -0,0 +1,491 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateeditmatrixvectordialog.h"
#include "qalculate_kde_utils.h"
#include "qalculateeditnamesdialog.h"
#include <qgrid.h>
#include <klineedit.h>
#include <qpushbutton.h>
#include <kcombobox.h>
#include <qlabel.h>
#include <klocale.h>
#include <qvbox.h>
#include <qhbox.h>
#include <qcheckbox.h>
#include <kmessagebox.h>
#include <qspinbox.h>
#include <qlayout.h>
#include <qbuttongroup.h>
#include <qradiobutton.h>
#include <qtable.h>
#include <kapplication.h>
extern PrintOptions printops;
extern EvaluationOptions evalops;
extern tree_struct variable_cats;
class QalculateEditMatrixVectorTableItem : public QTableItem {
public:
QalculateEditMatrixVectorTableItem(QTable *table);
QalculateEditMatrixVectorTableItem(QTable *table, const QString & text);
int alignment() const;
};
class QalculateEditMatrixTable : public QTable {
public:
QalculateEditMatrixTable(QWidget *parent = 0, const char *name = 0) : QTable(parent, name) {}
QalculateEditMatrixTable(int numRows, int numCols, QWidget *parent = 0, const char *name = 0) : QTable(numRows, numCols, parent, name) {}
QWidget *beginEdit(int row, int col, bool replace) {
QWidget *w = QTable::beginEdit(row, col, replace);
((QLineEdit*) w)->selectAll();
return w;
}
};
QalculateEditMatrixVectorDialog::QalculateEditMatrixVectorDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Variable"), Ok | Cancel | Help, Ok, true) {
names_edit_dialog = NULL;
edited_variable = NULL;
setMainWidget(new QWidget(this));
QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 0, 0);
nameEdit = new KLineEdit(mainWidget());
grid->addWidget(nameEdit, 0, 1);
QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
namesLabel = new QLabel(mainWidget());
namesLabel->setAlignment(Qt::AlignRight);
namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hbox->addWidget(namesLabel);
namesButton = new QPushButton(i18n("Names Details"), mainWidget());
hbox->addWidget(namesButton);
grid->addWidget(new QLabel(i18n("Category:"), mainWidget()), 2, 0);
categoryCombo = new KComboBox(mainWidget());
categoryCombo->setEditable(true);
grid->addWidget(categoryCombo, 2, 1);
grid->addWidget(new QLabel(i18n("Descriptive name:"), mainWidget()), 3, 0);
titleEdit = new KLineEdit(mainWidget());
grid->addWidget(titleEdit, 3, 1);
grid->addWidget(new QLabel(i18n("Rows:"), mainWidget()), 4, 0);
rowsBox = new QSpinBox(1, 1000, 1, mainWidget());
grid->addWidget(rowsBox, 4, 1);
grid->addWidget(new QLabel(i18n("Columns:"), mainWidget()), 5, 0);
columnsBox = new QSpinBox(1, 1000, 1, mainWidget());
grid->addWidget(columnsBox, 5, 1);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 6, 6, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
QButtonGroup *group = new QButtonGroup();
matrixButton = new QRadioButton(i18n("Matrix"), mainWidget());
group->insert(matrixButton, 0);
hbox->addWidget(matrixButton);
vectorButton = new QRadioButton(i18n("Vector"), mainWidget());
group->insert(vectorButton, 1);
hbox->addWidget(vectorButton);
elementsLabel = new QLabel(i18n("Elements:"), mainWidget());
grid->addMultiCellWidget(elementsLabel, 7, 7, 0, 1);
elementsTable = new QalculateEditMatrixTable(0, 0, mainWidget());
grid->addMultiCellWidget(elementsTable, 8, 8, 0, 1);
connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
connect(rowsBox, SIGNAL(valueChanged(int)), this, SLOT(rowsChanged(int)));
connect(columnsBox, SIGNAL(valueChanged(int)), this, SLOT(columnsChanged(int)));
connect(group, SIGNAL(clicked(int)), this, SLOT(typeChanged(int)));
}
QalculateEditMatrixVectorDialog::~QalculateEditMatrixVectorDialog() {}
void QalculateEditMatrixVectorDialog::slotHelp() {
KApplication::kApplication()->invokeHelp("qalculate-vectors-matrices");
}
void QalculateEditMatrixVectorDialog::typeChanged(int i) {
if(i == 0) {
elementsLabel->setText(i18n("Elements:"));
bool b = true;
for(int index_r = elementsTable->numRows() - 1; index_r >= 0 && b; index_r--) {
for(int index_c = elementsTable->numCols() - 1; index_c >= 0; index_c--) {
if(elementsTable->text(index_r, index_c).isEmpty()) {
elementsTable->setText(index_r, index_c, "0");
} else {
b = false;
break;
}
}
}
} else {
elementsLabel->setText(i18n("Elements (in horizontal order):"));
}
}
void QalculateEditMatrixVectorDialog::rowsChanged(int i) {
int r = elementsTable->numRows();
elementsTable->setNumRows(i);
bool b = matrixButton->isChecked();
for(int index_r = r; index_r < i; index_r++) {
for(int index_c = 0; index_c < elementsTable->numCols(); index_c++) {
if(b) elementsTable->setItem(index_r, index_c, new QalculateEditMatrixVectorTableItem(elementsTable, "0"));
else elementsTable->setItem(index_r, index_c, new QalculateEditMatrixVectorTableItem(elementsTable));
}
}
}
void QalculateEditMatrixVectorDialog::columnsChanged(int i) {
int c = elementsTable->numCols();
elementsTable->setNumCols(i);
bool b = matrixButton->isChecked();
for(int index_r = 0; index_r < elementsTable->numRows(); index_r++) {
for(int index_c = c; index_c < i; index_c++) {
if(b) elementsTable->setItem(index_r, index_c, new QalculateEditMatrixVectorTableItem(elementsTable, "0"));
else elementsTable->setItem(index_r, index_c, new QalculateEditMatrixVectorTableItem(elementsTable));
}
}
}
KnownVariable *QalculateEditMatrixVectorDialog::newVector(QString category) {
return editVariable(category, NULL, NULL, false, true);
}
KnownVariable *QalculateEditMatrixVectorDialog::newMatrix(QString category) {
return editVariable(category, NULL, NULL, false, false);
}
void QalculateEditMatrixVectorDialog::slotOk() {
string str = nameEdit->text().ascii();
remove_blank_ends(str);
if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
//no name -- open dialog again
nameEdit->setFocus();
KMessageBox::error(this, i18n("Empty name field"));
return;
}
//variable with the same name exists -- overwrite or open dialog again
if((!edited_variable || !edited_variable->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->variableNameTaken(str, edited_variable) && KMessageBox::questionYesNo(this, i18n("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
nameEdit->setFocus();
return;
}
KnownVariable *v = edited_variable;
if(!v) {
//no need to create a new variable when a variable with the same name exists
Variable *var = CALCULATOR->getActiveVariable(str);
if(var && var->isLocal() && var->isKnown()) v = (KnownVariable*) var;
}
MathStructure mstruct_new;
if(!init_value) {
int r = rowsBox->value();
int c = columnsBox->value();
if(vectorButton->isChecked()) {
mstruct_new.clearVector();
string str2;
for(int index_r = 0; index_r < r; index_r++) {
for(int index_c = 0; index_c < c; index_c++) {
if(!elementsTable->text(index_r, index_c).isEmpty()) {
str2 = elementsTable->text(index_r, index_c).ascii();
remove_blank_ends(str2);
if(!str2.empty()) {
mstruct_new.addChild(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str2, evalops.parse_options)));
}
}
}
}
} else {
mstruct_new.clearMatrix();
mstruct_new.resizeMatrix(r, c, m_undefined);
for(int index_r = 0; index_r < r; index_r++) {
for(int index_c = 0; index_c < c; index_c++) {
if(elementsTable->text(index_r, index_c).isEmpty()) mstruct_new.setElement(m_zero, index_r + 1, index_c + 1);
else mstruct_new.setElement(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(elementsTable->text(index_r, index_c).ascii(), evalops.parse_options)), index_r + 1, index_c + 1);
}
}
}
}
bool add_var = false;
if(v) {
//update existing variable
v->setLocal(true);
if(!v->isBuiltin()) {
if(init_value) {
v->set(*init_value);
} else {
v->set(mstruct_new);
}
}
} else {
//new variable
if(force_init_value && init_value) {
//forced value
v = new KnownVariable("", "", *init_value, "", true);
} else {
v = new KnownVariable("", "", mstruct_new, "", true);
}
add_var = true;
}
v->setCategory(categoryCombo->lineEdit()->text().ascii());
v->setTitle(titleEdit->text().ascii());
if(!v->isBuiltin()) {
if(names_edit_dialog) {
names_edit_dialog->saveNames(v, str.c_str());
} else {
if(v->countNames() == 0) {
ExpressionName ename(str);
ename.reference = true;
v->setName(ename, 1);
} else {
v->setName(str, 1);
}
}
}
if(add_var) {
CALCULATOR->addVariable(v);
}
edited_variable = v;
accept();
}
KnownVariable *QalculateEditMatrixVectorDialog::editVariable(QString category, KnownVariable *v, MathStructure *initial_value, bool force_value, bool create_vector) {
nameEdit->setFocus();
if((v && !v->get().isVector()) || (initial_value && !initial_value->isVector())) {
return NULL;
}
if(names_edit_dialog) {
delete names_edit_dialog;
names_edit_dialog = NULL;
}
edited_variable = v;
if(initial_value) {
create_vector = !initial_value->isMatrix();
} else if(v) {
create_vector = !v->get().isMatrix();
}
if(create_vector) {
vectorButton->setChecked(true);
elementsLabel->setText(i18n("Elements (in horizontal order):"));
} else {
matrixButton->setChecked(true);
elementsLabel->setText(i18n("Elements:"));
}
if(create_vector) {
if(v) {
if(v->isLocal())
setCaption(i18n("Edit Vector"));
else
setCaption(i18n("Edit Vector (global)"));
} else {
setCaption(i18n("New Vector"));
}
} else {
if(v) {
if(v->isLocal())
setCaption(i18n("Edit Matrix"));
else
setCaption(i18n("Edit Matrix (global)"));
} else {
setCaption(i18n("New Matrix"));
}
}
actionButton(Ok)->setEnabled(true);
namesLabel->setText("");
//QStringList cats;
QString catstr;
categoryCombo->clear();
tree_struct *item, *item2;
variable_cats.it = variable_cats.items.begin();
if(variable_cats.it != variable_cats.items.end()) {
item = &*variable_cats.it;
++variable_cats.it;
item->it = item->items.begin();
} else {
item = NULL;
}
catstr = "";
while(item) {
if(!catstr.isEmpty()) catstr += "/";
catstr += item->item.c_str();
categoryCombo->insertItem(catstr);
while(item && item->it == item->items.end()) {
int str_i = catstr.findRev("/");
if(str_i < 0) {
catstr = "";
} else {
catstr.truncate(str_i);
}
item = item->parent;
}
if(item) {
item2 = &*item->it;
++item->it;
item = item2;
item->it = item->items.begin();
}
}
int r = 4, c = 4;
const MathStructure *old_vctr = NULL;
if(v) {
if(create_vector) {
old_vctr = &v->get();
} else {
c = v->get().columns();
r = v->get().rows();
}
set_name_label_and_entry(v, nameEdit, namesLabel);
nameEdit->setReadOnly(v->isBuiltin());
rowsBox->setEnabled(!v->isBuiltin());
columnsBox->setEnabled(!v->isBuiltin());
matrixButton->setEnabled(!v->isBuiltin());
vectorButton->setEnabled(!v->isBuiltin());
elementsTable->setReadOnly(v->isBuiltin());
categoryCombo->lineEdit()->setText(v->category().c_str());
titleEdit->setText(v->title(false).c_str());
} else {
nameEdit->setReadOnly(false);
rowsBox->setEnabled(true);
columnsBox->setEnabled(true);
matrixButton->setEnabled(true);
vectorButton->setEnabled(true);
elementsTable->setReadOnly(false);
//fill in default values
nameEdit->setText(CALCULATOR->getName().c_str());
namesLabel->setText("");
categoryCombo->lineEdit()->setText(category);
titleEdit->setText("");
if(force_value) {
if(create_vector) {
old_vctr = initial_value;
} else {
c = initial_value->columns();
r = initial_value->rows();
}
rowsBox->setEnabled(false);
columnsBox->setEnabled(false);
matrixButton->setEnabled(false);
vectorButton->setEnabled(false);
elementsTable->setReadOnly(true);
}
}
if(create_vector) {
if(old_vctr) {
r = old_vctr->countChildren();
c = (int) ::sqrt(r) + 4;
if(r % c > 0) {
r = r / c + 1;
} else {
r = r / c;
}
} else {
c = 4;
r = 4;
}
}
rowsBox->setValue(r);
columnsBox->setValue(c);
elementsTable->setNumRows(r);
elementsTable->setNumCols(c);
int timeout;
if(force_value) timeout = 3000 / (r * c);
else timeout = 3000;
PrintOptions po;
po.number_fraction_format = FRACTION_DECIMAL_EXACT;
for(int index_r = 0; index_r < r; index_r++) {
for(int index_c = 0; index_c < c; index_c++) {
if(create_vector) {
if(old_vctr && index_r * c + index_c < (int) old_vctr->countChildren()) {
elementsTable->setText(index_r, index_c, old_vctr->getChild(index_r * c + index_c + 1)->print(po).c_str());
} else {
elementsTable->setText(index_r, index_c, "");
}
} else {
if(v) {
elementsTable->setText(index_r, index_c, v->get().getElement(index_r + 1, index_c + 1)->print(po).c_str());
} else if(initial_value) {
elementsTable->setText(index_r, index_c, initial_value->getElement(index_r + 1, index_c + 1)->print(po).c_str());
} else {
elementsTable->setText(index_r, index_c, "0");
}
}
}
}
init_value = initial_value;
force_init_value = force_value;
if(exec() == QDialog::Accepted) {
v = edited_variable;
edited_variable = NULL;
return v;
}
edited_variable = NULL;
return NULL;
}
void QalculateEditMatrixVectorDialog::editNames() {
if(!names_edit_dialog) {
names_edit_dialog = new QalculateEditNamesDialog(TYPE_VARIABLE, this);
names_edit_dialog->setNames(edited_variable, nameEdit->text(), false);
} else {
names_edit_dialog->setNames(edited_variable, nameEdit->text(), true);
}
names_edit_dialog->exec();
names_edit_dialog->setNamesLE(nameEdit, namesLabel);
}
void QalculateEditMatrixVectorDialog::nameChanged(const QString &name) {
if(name.isNull()) return;
if(!CALCULATOR->variableNameIsValid(name.ascii())) {
nameEdit->blockSignals(true);
nameEdit->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str());
nameEdit->blockSignals(false);
}
}
#if QT_VERSION >= 0x030200
QalculateEditMatrixVectorTableItem::QalculateEditMatrixVectorTableItem(QTable *table) : QTableItem(table, QTableItem::OnTyping) {}
#else
QalculateEditMatrixVectorTableItem::QalculateEditMatrixVectorTableItem(QTable *table) : QTableItem(table, QTableItem::OnTyping, QString::null) {}
#endif
QalculateEditMatrixVectorTableItem::QalculateEditMatrixVectorTableItem(QTable *table, const QString & text) : QTableItem(table, QTableItem::OnTyping, text) {}
int QalculateEditMatrixVectorTableItem::alignment() const {return Qt::AlignRight;}
#include "qalculateeditmatrixvectordialog.moc"

@ -0,0 +1,82 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEEDITMATRIXVECTORDIALOG_H
#define QALCULATEEDITMATRIXVECTORDIALOG_H
#include <kdialogbase.h>
class QLabel;
class QSpinBox;
class QTable;
class QRadioButton;
class KComboBox;
class KLineEdit;
class QPushButton;
class MathStructure;
class QalculateEditNamesDialog;
class KnownVariable;
/**
@author Niklas Knutsson
*/
class QalculateEditMatrixVectorDialog : public KDialogBase {
Q_OBJECT
public:
QalculateEditMatrixVectorDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateEditMatrixVectorDialog();
KnownVariable *newMatrix(QString category = QString::null);
KnownVariable *newVector(QString category = QString::null);
KnownVariable *editVariable(QString category = QString::null, KnownVariable *v = NULL, MathStructure *initial_value = NULL, bool force_value = false, bool create_vector = false);
QalculateEditNamesDialog *names_edit_dialog;
KnownVariable *edited_variable;
KComboBox *categoryCombo;
KLineEdit *nameEdit, *titleEdit;
QLabel *namesLabel, *elementsLabel;
QRadioButton *matrixButton, *vectorButton;
QTable *elementsTable;
QSpinBox *rowsBox, *columnsBox;
QPushButton *namesButton;
private:
MathStructure *init_value;
bool force_init_value;
public slots:
void typeChanged(int);
void rowsChanged(int);
void columnsChanged(int);
void editNames();
void nameChanged(const QString&);
protected slots:
void slotHelp();
void slotOk();
};
#endif

@ -0,0 +1,275 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateeditnamesdialog.h"
#include "qalculate_kde_utils.h"
#include <klocale.h>
#include <klistview.h>
#include <kpushbutton.h>
#include <qlayout.h>
#include <klineedit.h>
#include <qlabel.h>
#include <qapplication.h>
#include <kstdguiitem.h>
QalculateEditNamesDialog::QalculateEditNamesDialog(int item_type, QWidget *parent, const char *name) : KDialog(parent, name, true) {
setCaption(i18n("Edit Names"));
i_type = item_type;
QVBoxLayout *layout = new QVBoxLayout(this, marginHint(), spacingHint());
namesView = new KListView(this);
namesView->addColumn(i18n("Name"));
namesView->addColumn(i18n("Abbreviation"));
namesView->setColumnAlignment(1, Qt::AlignCenter);
namesView->addColumn(i18n("Plural"));
namesView->setColumnAlignment(2, Qt::AlignCenter);
namesView->addColumn(i18n("Reference"));
namesView->setColumnAlignment(3, Qt::AlignCenter);
namesView->addColumn(i18n("Avoid Input"));
namesView->setColumnAlignment(4, Qt::AlignCenter);
namesView->addColumn(i18n("Unicode"));
namesView->setColumnAlignment(5, Qt::AlignCenter);
namesView->addColumn(i18n("Suffix"));
namesView->setColumnAlignment(6, Qt::AlignCenter);
namesView->addColumn(i18n("Case Sensitive"));
namesView->setColumnAlignment(7, Qt::AlignCenter);
namesView->setSorting(-1);
namesView->setItemsRenameable(true);
namesView->setItemsMovable(true);
namesView->setDragEnabled(true);
namesView->setAcceptDrops(true);
layout->addWidget(namesView);
QHBoxLayout *buttonLayout = new QHBoxLayout(layout, spacingHint());
newButton = new QPushButton(i18n("New"), this);
buttonLayout->addWidget(newButton);
deleteButton = new QPushButton(i18n("Delete"), this);
deleteButton->setEnabled(false);
buttonLayout->addWidget(deleteButton);
buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
buttonClose = new KPushButton(KStdGuiItem::close(), this);
buttonClose->setAutoDefault(true);
buttonClose->setDefault(true);
buttonLayout->addWidget(buttonClose);
connect(namesView, SIGNAL(selectionChanged()), this, SLOT(nameSelectionChanged()));
connect(buttonClose, SIGNAL(clicked()), this, SLOT(accept()));
connect(newButton, SIGNAL(clicked()), this, SLOT(newName()));
connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteName()));
connect(namesView, SIGNAL(clicked(QListViewItem*, const QPoint&, int)), this, SLOT(itemClicked(QListViewItem*, const QPoint&, int)));
connect(namesView->renameLineEdit(), SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
}
QalculateEditNamesDialog::~QalculateEditNamesDialog() {}
void QalculateEditNamesDialog::newName() {
ExpressionName name;
QListViewItem *i = new KListViewItem(namesView, namesView->lastChild(), "", i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"));
namesView->setSelected(i, true);
qApp->processEvents();
namesView->rename(i, 0);
}
void QalculateEditNamesDialog::setNames(ExpressionItem *item, const QString &namestr, bool names_edited) {
if(!names_edited) {
deleteButton->setEnabled(false);
namesView->clear();
}
if(!names_edited && item && item->countNames() > 0) {
QListViewItem *i_prev = NULL;
for(size_t index = 1; index <= item->countNames(); index++) {
const ExpressionName *ename = &item->getName(index);
QListViewItem *i = new KListViewItem(namesView, i_prev);
i_prev = i;
if(ename->abbreviation)
i->setText(1, i18n("Yes"));
else
i->setText(1, i18n("No"));
if(ename->plural)
i->setText(2, i18n("Yes"));
else
i->setText(2, i18n("No"));
if(ename->reference)
i->setText(3, i18n("Yes"));
else
i->setText(3, i18n("No"));
if(ename->avoid_input)
i->setText(4, i18n("Yes"));
else
i->setText(4, i18n("No"));
if(ename->unicode)
i->setText(5, i18n("Yes"));
else
i->setText(5, i18n("No"));
if(ename->suffix)
i->setText(6, i18n("Yes"));
else
i->setText(6, i18n("No"));
if(ename->case_sensitive)
i->setText(7, i18n("Yes"));
else
i->setText(7, i18n("No"));
if(index == 1 && !namestr.isEmpty()) {
i->setText(0, namestr);
} else {
i->setText(0, ename->name.c_str());
}
}
} else if(!namestr.isEmpty()) {
if(names_edited) {
QListViewItemIterator it(namesView);
if(it.current())
it.current()->setText(0, namestr);
} else {
ExpressionName ename(namestr.ascii());
QListViewItem *i = new KListViewItem(namesView, ename.name.c_str());
if(ename.abbreviation)
i->setText(1, i18n("Yes"));
else
i->setText(1, i18n("No"));
if(ename.plural)
i->setText(2, i18n("Yes"));
else
i->setText(2, i18n("No"));
if(ename.reference)
i->setText(3, i18n("Yes"));
else
i->setText(3, i18n("No"));
if(ename.avoid_input)
i->setText(4, i18n("Yes"));
else
i->setText(4, i18n("No"));
if(ename.unicode)
i->setText(5, i18n("Yes"));
else
i->setText(5, i18n("No"));
if(ename.suffix)
i->setText(6, i18n("Yes"));
else
i->setText(6, i18n("No"));
if(ename.case_sensitive)
i->setText(7, i18n("Yes"));
else
i->setText(7, i18n("No"));
}
}
}
void QalculateEditNamesDialog::saveNames(ExpressionItem *item, const QString &str) {
item->clearNames();
QListViewItemIterator it(namesView);
if(it.current()) {
bool b = false;
while(it.current()) {
ExpressionName ename;
if(b || str.isEmpty())
ename.name = it.current()->text(0).ascii();
else
ename.name = str.ascii();
ename.abbreviation = (it.current()->text(1) == i18n("Yes"));
ename.plural = (it.current()->text(2) == i18n("Yes"));
ename.reference = (it.current()->text(3) == i18n("Yes"));
ename.avoid_input = (it.current()->text(4) == i18n("Yes"));
ename.unicode = (it.current()->text(5) == i18n("Yes"));
ename.suffix = (it.current()->text(6) == i18n("Yes"));
ename.case_sensitive = (it.current()->text(7) == i18n("Yes"));
item->addName(ename);
++it;
b = true;
}
} else {
item->addName(str.ascii());
}
}
void QalculateEditNamesDialog::setNamesLE(QLineEdit *entry, QLabel *label) {
int index = 0;
QString str;
QListViewItemIterator it(namesView);
while(it.current()) {
if(index == 0) {
entry->setText(it.current()->text(0));
} else {
if(index == 1) {
str = "+ ";
} else {
str += ", ";
}
str += it.current()->text(0);
}
++it;
index++;
}
label->setText(str);
}
bool QalculateEditNamesDialog::isEmpty() {
return namesView->childCount() <= 0;
}
void QalculateEditNamesDialog::deleteName() {
namesView->removeItem(namesView->selectedItem());
}
void QalculateEditNamesDialog::itemClicked(QListViewItem *i, const QPoint &, int c) {
if(i && c > 0) {
if(i->text(c) == i18n("Yes"))
i->setText(c, i18n("No"));
else
i->setText(c, i18n("Yes"));
if(c == 1)
i->setText(7, i->text(c));
}
}
void QalculateEditNamesDialog::nameSelectionChanged() {
deleteButton->setEnabled(namesView->selectedItem() != NULL);
}
void QalculateEditNamesDialog::nameChanged(const QString &name) {
if(name.isNull()) return;
namesView->renameLineEdit()->blockSignals(true);
switch(i_type) {
case TYPE_VARIABLE: {
if(!CALCULATOR->variableNameIsValid(name.ascii())) {
namesView->renameLineEdit()->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str());
}
break;
}
case TYPE_UNIT: {
if(!CALCULATOR->unitNameIsValid(name.ascii())) {
namesView->renameLineEdit()->setText(CALCULATOR->convertToValidUnitName(name.ascii()).c_str());
}
break;
}
case TYPE_FUNCTION: {
if(!CALCULATOR->functionNameIsValid(name.ascii())) {
namesView->renameLineEdit()->setText(CALCULATOR->convertToValidFunctionName(name.ascii()).c_str());
}
break;
}
}
namesView->renameLineEdit()->blockSignals(false);
}
#include "qalculateeditnamesdialog.moc"

@ -0,0 +1,65 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEEDITNAMESDIALOG_H
#define QALCULATEEDITNAMESDIALOG_H
#include <kdialog.h>
class ExpressionItem;
class KListView;
class QPushButton;
class QLineEdit;
class QLabel;
class QListViewItem;
/**
@author Niklas Knutsson
*/
class QalculateEditNamesDialog : public KDialog {
Q_OBJECT
public:
QalculateEditNamesDialog(int item_type, QWidget *parent = 0, const char *name = 0);
virtual ~QalculateEditNamesDialog();
void saveNames(ExpressionItem *item, const QString &str = QString::null);
void setNames(ExpressionItem *item = NULL, const QString &namestr = QString::null, bool names_edited = false);
bool isEmpty();
void setNamesLE(QLineEdit *entry, QLabel *label);
KListView* namesView;
QPushButton* newButton;
QPushButton* deleteButton;
QPushButton* buttonClose;
int i_type;
public slots:
virtual void itemClicked(QListViewItem*, const QPoint&, int);
virtual void newName();
virtual void deleteName();
virtual void nameChanged(const QString&);
virtual void nameSelectionChanged();
};
#endif

@ -0,0 +1,425 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateeditunitdialog.h"
#include "qalculate_kde_utils.h"
#include "qalculateeditnamesdialog.h"
#include <qgrid.h>
#include <klineedit.h>
#include <qpushbutton.h>
#include <kcombobox.h>
#include <qlabel.h>
#include <klocale.h>
#include <qvbox.h>
#include <qhbox.h>
#include <qcheckbox.h>
#include <kmessagebox.h>
#include <qgroupbox.h>
#include <qspinbox.h>
#include <qlayout.h>
#include <kapplication.h>
extern PrintOptions printops;
extern EvaluationOptions evalops;
extern tree_struct unit_cats;
QalculateEditUnitDialog::QalculateEditUnitDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Unit"), Ok | Cancel | Help, Ok, true) {
names_edit_dialog = NULL;
edited_unit = NULL;
QVBox *box = makeVBoxMainWidget();
grid1 = new QGroupBox(1, Qt::Horizontal, i18n("Name"), box);
grid1->setInsideMargin(spacingHint());
grid1->setInsideSpacing(spacingHint());
QWidget *widget = new QWidget(grid1);
QGridLayout *grid = new QGridLayout(widget, 1, 1, 0, spacingHint());
grid->addWidget(new QLabel(i18n("Name:"), widget), 0, 0);
nameEdit = new KLineEdit(widget);
grid->addWidget(nameEdit, 0, 1);
QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
namesLabel = new QLabel(widget);
namesLabel->setAlignment(Qt::AlignRight);
namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hbox->addWidget(namesLabel);
namesButton = new QPushButton(i18n("Names Details"), widget);
hbox->addWidget(namesButton);
grid->addWidget(new QLabel(i18n("Descriptive name:"), widget), 2, 0);
titleEdit = new KLineEdit(widget);
grid->addWidget(titleEdit, 2, 1);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 3, 3, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
hideButton = new QCheckBox(i18n("Hide unit"), widget);
hbox->addWidget(hideButton);
grid2 = new QGroupBox(1, Qt::Horizontal, i18n("Type"), box);
grid2->setInsideMargin(spacingHint());
grid2->setInsideSpacing(spacingHint());
widget = new QWidget(grid2);
grid = new QGridLayout(widget, 1, 1, 0, spacingHint());
grid->addWidget(new QLabel(i18n("Class:"), widget), 0, 0);
classCombo = new KComboBox(widget);
grid->addWidget(classCombo, 0, 1);
classCombo->insertItem(i18n("Base Unit"));
classCombo->insertItem(i18n("Alias"));
classCombo->insertItem(i18n("Composite Unit"));
classCombo->setMaximumWidth(250);
grid->addWidget(new QLabel(i18n("Category:"), widget), 1, 0);
categoryCombo = new KComboBox(widget);
grid->addWidget(categoryCombo, 1, 1);
categoryCombo->setMaximumWidth(250);
categoryCombo->setEditable(true);
grid->addWidget(new QLabel(i18n("System:"), widget), 2, 0);
systemCombo = new KComboBox(widget);
grid->addWidget(systemCombo, 2, 1);
systemCombo->insertItem(i18n("SI"));
systemCombo->insertItem(i18n("CGS"));
systemCombo->insertItem(i18n("Imperial"));
systemCombo->insertItem(i18n("US Survey"));
systemCombo->setMaximumWidth(250);
systemCombo->setEditable(true);
grid3 = new QGroupBox(1, Qt::Horizontal, i18n("Relation"), box);
grid3->setInsideMargin(spacingHint());
grid3->setInsideSpacing(spacingHint());
widget = new QWidget(grid3);
grid = new QGridLayout(widget, 1, 1, 0, spacingHint());
grid->addWidget(new QLabel(i18n("Base unit:"), widget), 0, 0);
baseEdit = new KLineEdit(widget);
grid->addWidget(baseEdit, 0, 1);
exponentLabel = new QLabel(i18n("Exponent:"), widget);
grid->addWidget(exponentLabel, 1, 0);
exponentBox = new QSpinBox(-9, 9, 1, widget);
grid->addWidget(exponentBox, 1, 1);
relationLabel = new QLabel(i18n("Relation:"), widget);
grid->addWidget(relationLabel, 2, 0);
relationEdit = new KLineEdit(widget);
grid->addWidget(relationEdit, 2, 1);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 3, 3, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
relationExactButton = new QCheckBox(i18n("Relation is exact"), widget);
hbox->addWidget(relationExactButton);
inverseRelationLabel = new QLabel(i18n("Inverse relation:"), widget);
grid->addWidget(inverseRelationLabel, 4, 0);
inverseRelationEdit = new KLineEdit(widget);
grid->addWidget(inverseRelationEdit, 4, 1);
connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
connect(classCombo, SIGNAL(activated(int)), this, SLOT(classChanged(int)));
connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
}
QalculateEditUnitDialog::~QalculateEditUnitDialog() {}
void QalculateEditUnitDialog::slotHelp() {
KApplication::kApplication()->invokeHelp("qalculate-unit-creation");
}
void QalculateEditUnitDialog::slotOk() {
string str = nameEdit->text().ascii();
remove_blank_ends(str);
if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
//no name -- open dialog again
nameEdit->setFocus();
KMessageBox::error(this, i18n("Empty name field"));
return;
}
//unit with the same name exists -- overwrite or open dialog again
if((!edited_unit || !edited_unit->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->unitNameTaken(str, edited_unit) && KMessageBox::questionYesNo(this, i18n("A variable or unit with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
nameEdit->setFocus();
return;
}
Unit *u = edited_unit;
bool add_unit = false;
if(u) {
//edited an existing unit -- update unit
u->setLocal(true);
int i1 = classCombo->currentItem();
switch(u->subtype()) {
case SUBTYPE_ALIAS_UNIT: {
if(i1 != 1) {
u->destroy();
u = NULL;
break;
}
if(!u->isBuiltin()) {
AliasUnit *au = (AliasUnit*) u;
Unit *bu = CALCULATOR->getUnit(baseEdit->text().ascii());
if(!bu) bu = CALCULATOR->getCompositeUnit(baseEdit->text().ascii());
if(!bu) {
baseEdit->setFocus();
KMessageBox::error(this, i18n("Base unit does not exist"));
return;
}
au->setBaseUnit(bu);
au->setExpression(CALCULATOR->unlocalizeExpression(relationEdit->text().ascii(), evalops.parse_options));
au->setInverseExpression(CALCULATOR->unlocalizeExpression(inverseRelationEdit->text().ascii(), evalops.parse_options));
au->setExponent(exponentBox->value());
au->setApproximate(!relationExactButton->isChecked());
}
break;
}
case SUBTYPE_COMPOSITE_UNIT: {
if(i1 != 2) {
u->destroy();
u = NULL;
break;
}
if(!u->isBuiltin()) {
((CompositeUnit*) u)->setBaseExpression(baseEdit->text().ascii());
}
break;
}
case SUBTYPE_BASE_UNIT: {
if(i1 != 0) {
u->destroy();
u = NULL;
break;
}
break;
}
}
if(u) {
u->setTitle(titleEdit->text().ascii());
u->setCategory(categoryCombo->lineEdit()->text().ascii());
}
}
if(!u) {
//new unit
switch(classCombo->currentItem()) {
case 1: {
Unit *bu = CALCULATOR->getUnit(baseEdit->text().ascii());
if(!bu) bu = CALCULATOR->getCompositeUnit(baseEdit->text().ascii());
if(!bu) {
baseEdit->setFocus();
KMessageBox::error(this, i18n("Base unit does not exist"));
return;
}
u = new AliasUnit(categoryCombo->lineEdit()->text().ascii(), "", "", "", titleEdit->text().ascii(), bu, CALCULATOR->unlocalizeExpression(relationEdit->text().ascii(), evalops.parse_options), exponentBox->value(), CALCULATOR->unlocalizeExpression(inverseRelationEdit->text().ascii(), evalops.parse_options), true);
((AliasUnit*) u)->setApproximate(!relationExactButton->isChecked());
break;
}
case 2: {
CompositeUnit *cu = new CompositeUnit(categoryCombo->lineEdit()->text().ascii(), "", titleEdit->text().ascii(), baseEdit->text().ascii(), true);
u = cu;
break;
}
default: {
u = new Unit(categoryCombo->lineEdit()->text().ascii(), "", "", "", titleEdit->text().ascii(), true);
break;
}
}
add_unit = true;
}
if(u) {
u->setHidden(hideButton->isChecked());
if(!u->isBuiltin()) {
u->setSystem(systemCombo->lineEdit()->text().ascii());
if(names_edit_dialog) {
names_edit_dialog->saveNames(u, str.c_str());
} else {
if(u->countNames() == 0) {
ExpressionName ename(str);
ename.reference = true;
u->setName(ename, 1);
} else {
u->setName(str, 1);
}
}
}
if(add_unit) {
CALCULATOR->addUnit(u);
}
}
edited_unit = u;
accept();
}
void QalculateEditUnitDialog::classChanged(int i) {
exponentBox->setEnabled(i == 1);
relationEdit->setEnabled(i == 1);
relationExactButton->setEnabled(i == 1);
inverseRelationEdit->setEnabled(i == 1);
exponentLabel->setEnabled(i == 1);
relationLabel->setEnabled(i == 1);
inverseRelationLabel->setEnabled(i == 1);
grid3->setEnabled(i != 0);
}
Unit *QalculateEditUnitDialog::editUnit(QString category, Unit *u) {
nameEdit->setFocus();
if(names_edit_dialog) {
delete names_edit_dialog;
names_edit_dialog = NULL;
}
edited_unit = u;
if(u) {
if(u->isLocal())
setCaption(i18n("Edit Unit"));
else
setCaption(i18n("Edit Unit (global)"));
} else {
setCaption(i18n("New Unit"));
}
//QStringList cats;
QString catstr;
categoryCombo->clear();
tree_struct *item, *item2;
unit_cats.it = unit_cats.items.begin();
if(unit_cats.it != unit_cats.items.end()) {
item = &*unit_cats.it;
++unit_cats.it;
item->it = item->items.begin();
} else {
item = NULL;
}
catstr = "";
while(item) {
if(!catstr.isEmpty()) catstr += "/";
catstr += item->item.c_str();
categoryCombo->insertItem(catstr);
while(item && item->it == item->items.end()) {
int str_i = catstr.findRev("/");
if(str_i < 0) {
catstr = "";
} else {
catstr.truncate(str_i);
}
item = item->parent;
}
if(item) {
item2 = &*item->it;
++item->it;
item = item2;
item->it = item->items.begin();
}
}
categoryCombo->lineEdit()->setText(category);
//clear entries
nameEdit->clear();
titleEdit->clear();
baseEdit->clear();
relationEdit->clear();
inverseRelationEdit->clear();
systemCombo->lineEdit()->clear();
exponentBox->setValue(1);
namesLabel->clear();
actionButton(Ok)->setEnabled(true);
nameEdit->setReadOnly(u && u->isBuiltin());
relationEdit->setReadOnly(u && u->isBuiltin());
inverseRelationEdit->setReadOnly(u && u->isBuiltin());
systemCombo->setEnabled(!u || !u->isBuiltin());
classCombo->setEnabled(!u || !u->isBuiltin());
baseEdit->setReadOnly(u && u->isBuiltin());
if(u) {
//fill in original parameters
if(u->subtype() == SUBTYPE_BASE_UNIT) {
classCombo->setCurrentItem(0);
classChanged(0);
} else if(u->subtype() == SUBTYPE_ALIAS_UNIT) {
classCombo->setCurrentItem(1);
classChanged(1);
} else if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) {
classCombo->setCurrentItem(2);
classChanged(2);
}
set_name_label_and_entry(u, nameEdit, namesLabel);
systemCombo->lineEdit()->setText(u->system().c_str());
hideButton->setChecked(u->isHidden());
categoryCombo->lineEdit()->setText(u->category().c_str());
titleEdit->setText(u->title(false).c_str());
switch(u->subtype()) {
case SUBTYPE_ALIAS_UNIT: {
AliasUnit *au = (AliasUnit*) u;
baseEdit->setText(((CompositeUnit*) (au->firstBaseUnit()))->preferredDisplayName(printops.abbreviate_names, true, false, false, &can_display_unicode_string_function, (void*) baseEdit).name.c_str());
exponentBox->setValue(au->firstBaseExponent());
relationEdit->setText(CALCULATOR->localizeExpression(au->expression()).c_str());
inverseRelationEdit->setText(CALCULATOR->localizeExpression(au->inverseExpression()).c_str());
relationExactButton->setChecked(!au->isApproximate());
relationEdit->setEnabled(true);
inverseRelationEdit->setEnabled(true);
relationExactButton->setEnabled(!u->isBuiltin());
exponentBox->setEnabled(!u->isBuiltin());
baseEdit->setEnabled(true);
break;
}
case SUBTYPE_COMPOSITE_UNIT: {
baseEdit->setText(((CompositeUnit*) u)->print(false, printops.abbreviate_names, true, &can_display_unicode_string_function, (void*) baseEdit).c_str());
baseEdit->setEnabled(true);
}
}
} else {
//default values
hideButton->setChecked(false);
relationExactButton->setChecked(true);
relationEdit->setText("1");
classCombo->setCurrentItem(1);
classChanged(1);
}
if(exec() == QDialog::Accepted) {
u = edited_unit;
edited_unit = NULL;
return u;
}
edited_unit = NULL;
return NULL;
}
void QalculateEditUnitDialog::editNames() {
if(!names_edit_dialog) {
names_edit_dialog = new QalculateEditNamesDialog(TYPE_UNIT, this);
names_edit_dialog->setNames(edited_unit, nameEdit->text(), false);
} else {
names_edit_dialog->setNames(edited_unit, nameEdit->text(), true);
}
names_edit_dialog->exec();
names_edit_dialog->setNamesLE(nameEdit, namesLabel);
}
void QalculateEditUnitDialog::nameChanged(const QString &name) {
if(name.isNull()) return;
if(!CALCULATOR->unitNameIsValid(name.ascii())) {
nameEdit->blockSignals(true);
nameEdit->setText(CALCULATOR->convertToValidUnitName(name.ascii()).c_str());
nameEdit->blockSignals(false);
}
}
#include "qalculateeditunitdialog.moc"

@ -0,0 +1,73 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEEDITUNITDIALOG_H
#define QALCULATEEDITUNITDIALOG_H
#include <kdialogbase.h>
class QLabel;
class KComboBox;
class KLineEdit;
class QCheckBox;
class QPushButton;
class QSpinBox;
class MathStructure;
class QalculateEditNamesDialog;
class Unit;
class QGroupBox;
/**
@author Niklas Knutsson
*/
class QalculateEditUnitDialog : public KDialogBase {
Q_OBJECT
public:
QalculateEditUnitDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateEditUnitDialog();
Unit *editUnit(QString category = QString::null, Unit *u = NULL);
QalculateEditNamesDialog *names_edit_dialog;
Unit *edited_unit;
KComboBox *categoryCombo, *classCombo, *systemCombo;
KLineEdit *nameEdit, *titleEdit, *baseEdit, *relationEdit, *inverseRelationEdit;
QLabel *namesLabel, *exponentLabel, *relationLabel, *inverseRelationLabel;
QCheckBox *relationExactButton, *hideButton;
QPushButton *namesButton;
QSpinBox *exponentBox;
QGroupBox *grid1, *grid2, *grid3;
public slots:
void editNames();
void classChanged(int);
void nameChanged(const QString&);
protected slots:
void slotHelp();
void slotOk();
};
#endif

@ -0,0 +1,308 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateeditunknownvariabledialog.h"
#include "qalculate_kde_utils.h"
#include "qalculateeditnamesdialog.h"
#include <qgrid.h>
#include <klineedit.h>
#include <qpushbutton.h>
#include <kcombobox.h>
#include <qlabel.h>
#include <klocale.h>
#include <qvbox.h>
#include <qhbox.h>
#include <qcheckbox.h>
#include <kmessagebox.h>
#include <qlayout.h>
#include <kapplication.h>
extern PrintOptions printops;
extern tree_struct variable_cats;
QalculateEditUnknownVariableDialog::QalculateEditUnknownVariableDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Variable"), Ok | Cancel | Help, Ok, true) {
names_edit_dialog = NULL;
edited_unknown = NULL;
setMainWidget(new QWidget(this));
QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 0, 0);
nameEdit = new KLineEdit(mainWidget());
grid->addWidget(nameEdit, 0, 1);
QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
namesLabel = new QLabel(mainWidget());
namesLabel->setAlignment(Qt::AlignRight);
namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hbox->addWidget(namesLabel);
namesButton = new QPushButton(i18n("Names Details"), mainWidget());
hbox->addWidget(namesButton);
assumptionsBox = new QCheckBox(i18n("Custom assumptions:"), mainWidget());
grid->addMultiCellWidget(assumptionsBox, 2, 2, 0, 1);
typeLabel = new QLabel(i18n("Type"), mainWidget());
grid->addWidget(typeLabel, 3, 0);
typeCombo = new KComboBox(mainWidget());
typeCombo->setMaximumWidth(250);
typeCombo->setEditable(false);
typeCombo->insertItem(i18n("Unknown"));
typeCombo->insertItem(i18n("Not Matrix"));
typeCombo->insertItem(i18n("Number"));
typeCombo->insertItem(i18n("Complex Number"));
typeCombo->insertItem(i18n("Real Number"));
typeCombo->insertItem(i18n("Rational Number"));
typeCombo->insertItem(i18n("Integer"));
grid->addWidget(typeCombo, 3, 1);
signLabel = new QLabel(i18n("Sign"), mainWidget());
grid->addWidget(signLabel, 4, 0);
signCombo = new KComboBox(mainWidget());
signCombo->setMaximumWidth(250);
signCombo->setEditable(false);
signCombo->insertItem(i18n("Unknown"));
signCombo->insertItem(i18n("Positive"));
signCombo->insertItem(i18n("Non-Negative"));
signCombo->insertItem(i18n("Negative"));
signCombo->insertItem(i18n("Non-Positive"));
signCombo->insertItem(i18n("Non-Zero"));
grid->addWidget(signCombo, 4, 1);
grid->addWidget(new QLabel(i18n("Category:"), mainWidget()), 5, 0);
categoryCombo = new KComboBox(mainWidget());
categoryCombo->setMaximumWidth(250);
categoryCombo->setEditable(true);
grid->addWidget(categoryCombo, 5, 1);
grid->addWidget(new QLabel(i18n("Descriptive name:"), mainWidget()), 6, 0);
titleEdit = new KLineEdit(mainWidget());
grid->addWidget(titleEdit, 6, 1);
connect(assumptionsBox, SIGNAL(toggled(bool)), typeCombo, SLOT(setEnabled(bool)));
connect(assumptionsBox, SIGNAL(toggled(bool)), signCombo, SLOT(setEnabled(bool)));
connect(assumptionsBox, SIGNAL(toggled(bool)), typeLabel, SLOT(setEnabled(bool)));
connect(assumptionsBox, SIGNAL(toggled(bool)), signLabel, SLOT(setEnabled(bool)));
connect(typeCombo, SIGNAL(activated(int)), this, SLOT(typeComboActivated(int)));
connect(signCombo, SIGNAL(activated(int)), this, SLOT(signComboActivated(int)));
connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
}
QalculateEditUnknownVariableDialog::~QalculateEditUnknownVariableDialog() {}
void QalculateEditUnknownVariableDialog::typeComboActivated(int i) {
if((AssumptionType) i <= ASSUMPTION_TYPE_COMPLEX && (AssumptionSign) signCombo->currentItem() != ASSUMPTION_SIGN_NONZERO) {
signCombo->blockSignals(true);
signCombo->setCurrentItem(ASSUMPTION_SIGN_UNKNOWN);
signCombo->blockSignals(false);
}
}
void QalculateEditUnknownVariableDialog::signComboActivated(int i) {
if((AssumptionSign) i != ASSUMPTION_SIGN_NONZERO && (AssumptionSign) i != ASSUMPTION_SIGN_UNKNOWN && (AssumptionType) typeCombo->currentItem() <= ASSUMPTION_TYPE_COMPLEX) {
typeCombo->blockSignals(true);
typeCombo->setCurrentItem(ASSUMPTION_TYPE_REAL);
typeCombo->blockSignals(false);
}
}
void QalculateEditUnknownVariableDialog::slotHelp() {
KApplication::kApplication()->invokeHelp("qalculate-variable-creation");
}
void QalculateEditUnknownVariableDialog::slotOk() {
string str = nameEdit->text().ascii();
remove_blank_ends(str);
if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
//no name -- open dialog again
nameEdit->setFocus();
KMessageBox::error(this, i18n("Empty name field"));
return;
}
//variable with the same name exists -- overwrite or open dialog again
if((!edited_unknown || !edited_unknown->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->variableNameTaken(str, edited_unknown) && KMessageBox::questionYesNo(this, i18n("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
nameEdit->setFocus();
return;
}
UnknownVariable *v = edited_unknown;
if(!v) {
//no need to create a new variable when a variable with the same name exists
Variable *var = CALCULATOR->getActiveVariable(str);
if(var && var->isLocal() && !var->isKnown()) v = (UnknownVariable*) var;
}
bool add_var = false;
if(v) {
//update existing variable
v->setLocal(true);
} else {
//new unknown variable
v = new UnknownVariable("", "", "", true);
add_var = true;
}
if(!v->isBuiltin()) {
if(assumptionsBox->isChecked()) {
if(!v->assumptions()) v->setAssumptions(new Assumptions());
v->assumptions()->setType((AssumptionType) typeCombo->currentItem());
v->assumptions()->setSign((AssumptionSign) signCombo->currentItem());
} else {
v->setAssumptions(NULL);
}
}
v->setCategory(categoryCombo->lineEdit()->text().ascii());
v->setTitle(titleEdit->text().ascii());
if(!v->isBuiltin()) {
if(names_edit_dialog) {
names_edit_dialog->saveNames(v, str.c_str());
} else {
if(v->countNames() == 0) {
ExpressionName ename(str);
ename.reference = true;
v->setName(ename, 1);
} else {
v->setName(str, 1);
}
}
}
if(add_var) {
CALCULATOR->addVariable(v);
}
edited_unknown = v;
accept();
}
UnknownVariable *QalculateEditUnknownVariableDialog::editVariable(QString category, UnknownVariable *v) {
nameEdit->setFocus();
if(names_edit_dialog) {
delete names_edit_dialog;
names_edit_dialog = NULL;
}
edited_unknown = v;
if(v) {
if(v->isLocal())
setCaption(i18n("Edit Unknown Variable"));
else
setCaption(i18n("Edit Unknown Variable (global)"));
} else {
setCaption(i18n("New Unknown Variable"));
}
actionButton(Ok)->setEnabled(true);
namesLabel->setText("");
//QStringList cats;
QString catstr;
categoryCombo->clear();
tree_struct *item, *item2;
variable_cats.it = variable_cats.items.begin();
if(variable_cats.it != variable_cats.items.end()) {
item = &*variable_cats.it;
++variable_cats.it;
item->it = item->items.begin();
} else {
item = NULL;
}
catstr = "";
while(item) {
if(!catstr.isEmpty()) catstr += "/";
catstr += item->item.c_str();
categoryCombo->insertItem(catstr);
while(item && item->it == item->items.end()) {
int str_i = catstr.findRev("/");
if(str_i < 0) {
catstr = "";
} else {
catstr.truncate(str_i);
}
item = item->parent;
}
if(item) {
item2 = &*item->it;
++item->it;
item = item2;
item->it = item->items.begin();
}
}
if(v) {
//fill in original parameters
set_name_label_and_entry(v, nameEdit, namesLabel);
nameEdit->setReadOnly(v->isBuiltin());
assumptionsBox->setEnabled(!v->isBuiltin());
categoryCombo->lineEdit()->setText(v->category().c_str());
titleEdit->setText(v->title(false).c_str());
if(v->assumptions()) {
assumptionsBox->setChecked(true);
typeCombo->setCurrentItem(v->assumptions()->type());
signCombo->setCurrentItem(v->assumptions()->sign());
} else {
assumptionsBox->setChecked(false);
typeCombo->setCurrentItem(CALCULATOR->defaultAssumptions()->type());
signCombo->setCurrentItem(CALCULATOR->defaultAssumptions()->sign());
}
} else {
nameEdit->setReadOnly(false);
assumptionsBox->setChecked(true);
//fill in default values
nameEdit->setText(CALCULATOR->getName().c_str());
namesLabel->setText("");
categoryCombo->lineEdit()->setText(category);
titleEdit->setText("");
typeCombo->setCurrentItem(CALCULATOR->defaultAssumptions()->type());
signCombo->setCurrentItem(CALCULATOR->defaultAssumptions()->sign());
}
signLabel->setEnabled(!v || (!v->isBuiltin() && v->assumptions()));
typeLabel->setEnabled(!v || (!v->isBuiltin() && v->assumptions()));
signCombo->setEnabled(!v || (!v->isBuiltin() && v->assumptions()));
typeCombo->setEnabled(!v || (!v->isBuiltin() && v->assumptions()));
if(exec() == QDialog::Accepted) {
v = edited_unknown;
edited_unknown = NULL;
return v;
}
edited_unknown = NULL;
return NULL;
}
void QalculateEditUnknownVariableDialog::editNames() {
if(!names_edit_dialog) {
names_edit_dialog = new QalculateEditNamesDialog(TYPE_VARIABLE, this);
names_edit_dialog->setNames(edited_unknown, nameEdit->text(), false);
} else {
names_edit_dialog->setNames(edited_unknown, nameEdit->text(), true);
}
names_edit_dialog->exec();
names_edit_dialog->setNamesLE(nameEdit, namesLabel);
}
void QalculateEditUnknownVariableDialog::nameChanged(const QString &name) {
if(name.isNull()) return;
if(!CALCULATOR->variableNameIsValid(name.ascii())) {
nameEdit->blockSignals(true);
nameEdit->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str());
nameEdit->blockSignals(false);
}
}
#include "qalculateeditunknownvariabledialog.moc"

@ -0,0 +1,70 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEEDITUNKNOWNVARIABLEDIALOG_H
#define QALCULATEEDITUNKNOWNVARIABLEDIALOG_H
#include <kdialogbase.h>
class QLabel;
class KComboBox;
class KLineEdit;
class QPushButton;
class MathStructure;
class QalculateEditNamesDialog;
class UnknownVariable;
class QCheckBox;
/**
@author Niklas Knutsson
*/
class QalculateEditUnknownVariableDialog : public KDialogBase {
Q_OBJECT
public:
QalculateEditUnknownVariableDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateEditUnknownVariableDialog();
UnknownVariable *editVariable(QString category = QString::null, UnknownVariable *v = NULL);
QalculateEditNamesDialog *names_edit_dialog;
UnknownVariable *edited_unknown;
KComboBox *categoryCombo, *signCombo, *typeCombo;
KLineEdit *nameEdit, *titleEdit;
QLabel *namesLabel, *signLabel, *typeLabel;
QPushButton *namesButton;
QCheckBox *assumptionsBox;
public slots:
void editNames();
void nameChanged(const QString&);
void signComboActivated(int);
void typeComboActivated(int);
protected slots:
void slotHelp();
void slotOk();
};
#endif

@ -0,0 +1,304 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateeditvariabledialog.h"
#include "qalculate_kde_utils.h"
#include "qalculateeditnamesdialog.h"
#include <qgrid.h>
#include <klineedit.h>
#include <qpushbutton.h>
#include <kcombobox.h>
#include <qlabel.h>
#include <klocale.h>
#include <qvbox.h>
#include <qhbox.h>
#include <qcheckbox.h>
#include <kmessagebox.h>
#include <qlayout.h>
#include <kapplication.h>
extern PrintOptions printops;
extern EvaluationOptions evalops;
extern tree_struct variable_cats;
QalculateEditVariableDialog::QalculateEditVariableDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Variable"), Ok | Cancel | Help, Ok, true) {
names_edit_dialog = NULL;
edited_variable = NULL;
setMainWidget(new QWidget(this));
QGridLayout *grid = new QGridLayout(mainWidget(), 6, 2, 0, spacingHint());
nameLabel = new QLabel(i18n("Name:"), mainWidget());
grid->addWidget(nameLabel, 0, 0);
nameEdit = new KLineEdit(mainWidget());
grid->addWidget(nameEdit, 0, 1);
QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
namesLabel = new QLabel(mainWidget());
namesLabel->setAlignment(Qt::AlignRight);
namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
hbox->addWidget(namesLabel);
namesButton = new QPushButton(i18n("Names Details"), mainWidget());
hbox->addWidget(namesButton);
valueLabel = new QLabel(i18n("Value:"), mainWidget());
grid->addWidget(valueLabel, 2, 0);
valueEdit = new KLineEdit(mainWidget());
grid->addWidget(valueEdit, 2, 1);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 3, 3, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
valueExactButton = new QCheckBox(i18n("Value is exact"), mainWidget());
hbox->addWidget(valueExactButton);
grid->addWidget(new QLabel(i18n("Category:"), mainWidget()), 4, 0);
categoryCombo = new KComboBox(mainWidget());
grid->addWidget(categoryCombo, 4, 1);
categoryCombo->setMaximumWidth(250);
categoryCombo->setEditable(true);
titleLabel = new QLabel(i18n("Descriptive name:"), mainWidget());
grid->addWidget(titleLabel, 5, 0);
titleEdit = new KLineEdit(mainWidget());
grid->addWidget(titleEdit, 5, 1);
connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames()));
connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
}
QalculateEditVariableDialog::~QalculateEditVariableDialog() {}
void QalculateEditVariableDialog::slotHelp() {
KApplication::kApplication()->invokeHelp("qalculate-variable-creation");
}
void QalculateEditVariableDialog::slotOk() {
string str = nameEdit->text().ascii();
remove_blank_ends(str);
if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) {
//no name -- open dialog again
nameEdit->setFocus();
KMessageBox::error(this, i18n("Empty name field"));
return;
}
string str2 = valueEdit->text().ascii();
remove_blank_ends(str2);
if(!(init_value && force_init_value) && str2.empty()) {
//no value -- open dialog again
valueEdit->setFocus();
KMessageBox::error(this, i18n("Empty value field"));
return;
}
//variable with the same name exists -- overwrite or open dialog again
if((!edited_variable || !edited_variable->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->variableNameTaken(str, edited_variable) && KMessageBox::questionYesNo(this, i18n("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) {
nameEdit->setFocus();
return;
}
KnownVariable *v = edited_variable;
if(!v) {
//no need to create a new variable when a variable with the same name exists
Variable *var = CALCULATOR->getActiveVariable(str);
if(var && var->isLocal() && var->isKnown()) v = (KnownVariable*) var;
}
bool add_var = false;
if(v) {
//update existing variable
v->setLocal(true);
if(!v->isBuiltin()) {
if(force_init_value && init_value) {
v->set(*init_value);
} else {
v->set(CALCULATOR->unlocalizeExpression(valueEdit->text().ascii(), evalops.parse_options));
v->setApproximate(!valueExactButton->isChecked());
}
}
} else {
//new variable
if(force_init_value && init_value) {
//forced value
v = new KnownVariable("", "", *init_value, "", true);
} else {
v = new KnownVariable("", "", CALCULATOR->unlocalizeExpression(valueEdit->text().ascii(), evalops.parse_options), "", true);
v->setApproximate(!valueExactButton->isChecked());
}
add_var = true;
}
v->setCategory(categoryCombo->lineEdit()->text().ascii());
v->setTitle(titleEdit->text().ascii());
if(!v->isBuiltin()) {
if(names_edit_dialog) {
names_edit_dialog->saveNames(v, str.c_str());
} else {
if(v->countNames() == 0) {
ExpressionName ename(str);
ename.reference = true;
v->setName(ename, 1);
} else {
v->setName(str, 1);
}
}
}
if(add_var) {
CALCULATOR->addVariable(v);
}
edited_variable = v;
accept();
}
KnownVariable *QalculateEditVariableDialog::editVariable(QString category, KnownVariable *v, MathStructure *initial_value, bool force_value) {
nameEdit->setFocus();
if(names_edit_dialog) {
delete names_edit_dialog;
names_edit_dialog = NULL;
}
edited_variable = v;
if(v) {
if(v->isLocal()) {
setCaption(i18n("Edit Variable"));
} else {
setCaption(i18n("Edit Variable (global)"));
}
} else {
setCaption(i18n("New Variable"));
}
actionButton(Ok)->setEnabled(true);
namesLabel->setText("");
//QStringList cats;
QString catstr;
categoryCombo->clear();
tree_struct *item, *item2;
variable_cats.it = variable_cats.items.begin();
if(variable_cats.it != variable_cats.items.end()) {
item = &*variable_cats.it;
++variable_cats.it;
item->it = item->items.begin();
} else {
item = NULL;
}
catstr = "";
while(item) {
if(!catstr.isEmpty()) catstr += "/";
catstr += item->item.c_str();
categoryCombo->insertItem(catstr);
while(item && item->it == item->items.end()) {
int str_i = catstr.findRev("/");
if(str_i < 0) {
catstr = "";
} else {
catstr.truncate(str_i);
}
item = item->parent;
}
if(item) {
item2 = &*item->it;
++item->it;
item = item2;
item->it = item->items.begin();
}
}
if(initial_value && force_value) {
valueEdit->hide();
valueLabel->hide();
namesButton->hide();
namesLabel->hide();
valueExactButton->hide();
} else {
valueEdit->show();
valueLabel->show();
namesButton->show();
namesLabel->show();
valueExactButton->show();
}
if(v) {
//fill in original parameters
set_name_label_and_entry(v, nameEdit, namesLabel);
valueEdit->setText(get_value_string(v->get(), false, NULL));
nameEdit->setReadOnly(v->isBuiltin());
valueEdit->setReadOnly(v->isBuiltin());
valueExactButton->setEnabled(!v->isBuiltin());
categoryCombo->lineEdit()->setText(v->category().c_str());
titleEdit->setText(v->title(false).c_str());
valueExactButton->setChecked(!(*printops.is_approximate) && !v->isApproximate());
} else {
nameEdit->setReadOnly(false);
valueEdit->setReadOnly(false);
valueExactButton->setEnabled(true);
//fill in default values
nameEdit->setText(CALCULATOR->getName().c_str());
namesLabel->setText("");
if(initial_value && !force_value) valueEdit->setText(get_value_string(*initial_value));
else valueEdit->setText("");
categoryCombo->lineEdit()->setText(category);
titleEdit->setText("");
if(initial_value) valueExactButton->setChecked(!initial_value->isApproximate());
else valueExactButton->setChecked(true);
if(force_value) {
valueEdit->setReadOnly(true);
valueExactButton->setEnabled(false);
}
}
init_value = initial_value;
force_init_value = force_value;
if(exec() == QDialog::Accepted) {
v = edited_variable;
edited_variable = NULL;
return v;
}
edited_variable = NULL;
return NULL;
}
void QalculateEditVariableDialog::editNames() {
if(!names_edit_dialog) {
names_edit_dialog = new QalculateEditNamesDialog(TYPE_VARIABLE, this);
names_edit_dialog->setNames(edited_variable, nameEdit->text(), false);
} else {
names_edit_dialog->setNames(edited_variable, nameEdit->text(), true);
}
names_edit_dialog->exec();
names_edit_dialog->setNamesLE(nameEdit, namesLabel);
}
void QalculateEditVariableDialog::nameChanged(const QString &name) {
if(name.isNull()) return;
if(!CALCULATOR->variableNameIsValid(name.ascii())) {
nameEdit->blockSignals(true);
nameEdit->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str());
nameEdit->blockSignals(false);
}
}
#include "qalculateeditvariabledialog.moc"

@ -0,0 +1,74 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEEDITVARIABLEDIALOG_H
#define QALCULATEEDITVARIABLEDIALOG_H
#include <kdialogbase.h>
class QLabel;
class KComboBox;
class KLineEdit;
class QCheckBox;
class QPushButton;
class MathStructure;
class QalculateEditNamesDialog;
class KnownVariable;
class QGridLayout;
/**
@author Niklas Knutsson
*/
class QalculateEditVariableDialog : public KDialogBase {
Q_OBJECT
public:
QalculateEditVariableDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateEditVariableDialog();
KnownVariable *editVariable(QString category = QString::null, KnownVariable *v = NULL, MathStructure *initial_value = NULL, bool force_value = false);
QalculateEditNamesDialog *names_edit_dialog;
KnownVariable *edited_variable;
KComboBox *categoryCombo;
KLineEdit *valueEdit, *nameEdit, *titleEdit;
QLabel *namesLabel, *titleLabel, *nameLabel, *valueLabel;
QCheckBox *valueExactButton;
QPushButton *namesButton;
private:
MathStructure *init_value;
bool force_init_value;
public slots:
void editNames();
void nameChanged(const QString&);
protected slots:
void slotHelp();
void slotOk();
};
#endif

@ -0,0 +1,186 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateexportcsvdialog.h"
#include "qalculate_kde_utils.h"
#include <qlayout.h>
#include <kurlrequester.h>
#include <klineedit.h>
#include <qlabel.h>
#include <qradiobutton.h>
#include <qpushbutton.h>
#include <kcombobox.h>
#include <qbuttongroup.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <kapplication.h>
extern MathStructure *mstruct;
QalculateExportCSVDialog::QalculateExportCSVDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Export CSV File"), Ok | Cancel | Help, Ok, true) {
setMainWidget(new QWidget(this));
QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
QButtonGroup *group = new QButtonGroup();
currentResultButton = new QRadioButton(i18n("Current result"), mainWidget());
group->insert(currentResultButton, 0);
grid->addWidget(currentResultButton, 0, 0);
currentResultButton->setChecked(true);
matrixVectorButton = new QRadioButton(i18n("Matrix/vector variable"), mainWidget());
group->insert(matrixVectorButton, 1);
grid->addWidget(matrixVectorButton, 1, 0);
matrixVectorEdit = new KLineEdit(mainWidget());
grid->addWidget(matrixVectorEdit, 1, 1);
grid->addWidget(new QLabel(i18n("File:"), mainWidget()), 2, 0);
fileEdit = new KURLRequester(mainWidget());
fileEdit->setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly);
fileEdit->setCaption(i18n("Export CSV File"));
grid->addWidget(fileEdit, 2, 1);
grid->addWidget(new QLabel(i18n("Delimiter:"), mainWidget()), 3, 0);
delimiterCombo = new KComboBox(mainWidget());
delimiterCombo->setMaximumWidth(250);
delimiterCombo->insertItem(i18n("Comma"));
delimiterCombo->insertItem(i18n("Tabulator"));
delimiterCombo->insertItem(i18n("Semicolon"));
delimiterCombo->insertItem(i18n("Space"));
delimiterCombo->insertItem(i18n("Other"));
delimiterCombo->setEditable(false);
grid->addWidget(delimiterCombo, 3, 1);
otherDelimiterEdit = new KLineEdit(mainWidget());
grid->addWidget(otherDelimiterEdit, 4, 1);
otherDelimiterEdit->setEnabled(false);
connect(group, SIGNAL(clicked(int)), this, SLOT(exportSourceChanged(int)));
connect(delimiterCombo, SIGNAL(activated(int)), this, SLOT(delimiterChanged(int)));
}
QalculateExportCSVDialog::~QalculateExportCSVDialog() {}
void QalculateExportCSVDialog::slotHelp() {
KApplication::kApplication()->invokeHelp("qalculate-import-export-csv");
}
void QalculateExportCSVDialog::exportSourceChanged(int i) {
matrixVectorEdit->setEnabled(i == 1);
}
void QalculateExportCSVDialog::delimiterChanged(int i) {
otherDelimiterEdit->setEnabled(i == 4);
}
void QalculateExportCSVDialog::slotOk() {
QString str = fileEdit->url().stripWhiteSpace();
if(str.isEmpty()) {
//no name -- open dialog again
fileEdit->setFocus();
KMessageBox::error(this, i18n("No file name entered."));
return;
}
string delimiter = "";
switch(delimiterCombo->currentItem()) {
case 0: {
delimiter = ",";
break;
}
case 1: {
delimiter = "\t";
break;
}
case 2: {
delimiter = ";";
break;
}
case 3: {
delimiter = " ";
break;
}
case 4: {
delimiter = otherDelimiterEdit->text().ascii();
break;
}
}
if(delimiter.empty()) {
//no delimiter -- open dialog again
otherDelimiterEdit->setFocus();
KMessageBox::error(this, i18n("No delimiter selected."));
return;
}
MathStructure *matrix_struct;
if(export_variable) {
matrix_struct = (MathStructure*) &export_variable->get();
} else if(currentResultButton->isChecked()) {
matrix_struct = mstruct;
} else {
string str2 = matrixVectorEdit->text().ascii();
remove_blank_ends(str2);
if(str2.empty()) {
matrixVectorEdit->setFocus();
KMessageBox::error(this, i18n("No variable name entered."));
return;
}
Variable *var = CALCULATOR->getActiveVariable(str2);
if(!var || !var->isKnown()) {
var = CALCULATOR->getVariable(str2);
while(var && !var->isKnown()) {
var = CALCULATOR->getVariable(str2);
}
}
if(!var || !var->isKnown()) {
matrixVectorEdit->setFocus();
KMessageBox::error(this, i18n("No known variable with entered name found."));
return;
}
matrix_struct = (MathStructure*) &((KnownVariable*) var)->get();
}
if(!CALCULATOR->exportCSV(*matrix_struct, str.ascii(), delimiter)) {
QString error_str;
error_str.sprintf(i18n("Could not export to file \n%s"), str.ascii());
KMessageBox::error(this, error_str);
reject();
}
accept();
}
void QalculateExportCSVDialog::exportCSVFile(KnownVariable *v) {
fileEdit->setFocus();
export_variable = v;
if(v) {
fileEdit->setURL(v->preferredDisplayName(false, false, false, false, &can_display_unicode_string_function, (void*) fileEdit->lineEdit()).name.c_str());
matrixVectorEdit->setText(v->preferredDisplayName(false, false, false, false, &can_display_unicode_string_function, (void*) matrixVectorEdit).name.c_str());
matrixVectorButton->setChecked(true);
} else {
fileEdit->clear();
matrixVectorEdit->clear();
currentResultButton->setChecked(true);
}
currentResultButton->setEnabled(v == NULL);
matrixVectorButton->setEnabled(v == NULL);
matrixVectorEdit->setEnabled(false);
exec();
}
#include "qalculateexportcsvdialog.moc"

@ -0,0 +1,66 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEEXPORTCSVDIALOG_H
#define QALCULATEEXPORTCSVDIALOG_H
#include <kdialogbase.h>
class KLineEdit;
class KComboBox;
class QRadioButton;
class KURLRequester;
class KnownVariable;
/**
@author Niklas Knutsson
*/
class QalculateExportCSVDialog : public KDialogBase {
Q_OBJECT
public:
QalculateExportCSVDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateExportCSVDialog();
KLineEdit *otherDelimiterEdit, *matrixVectorEdit;
KComboBox *delimiterCombo;
QRadioButton *currentResultButton, *matrixVectorButton;
KURLRequester *fileEdit;
void exportCSVFile(KnownVariable *v = NULL);
private:
KnownVariable *export_variable;
public slots:
void exportSourceChanged(int);
void delimiterChanged(int);
protected slots:
void slotHelp();
void slotOk();
};
#endif

File diff suppressed because it is too large Load Diff

@ -0,0 +1,109 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEEXPRESSIONEDIT_H
#define QALCULATEEXPRESSIONEDIT_H
#include <klineedit.h>
#include <kcompletionbox.h>
#include <kcompletion.h>
#include <qvaluevector.h>
class QStringList;
class QPopupMenu;
class QalculateExpressionEditCompletionBox;
class ExpressionItem;
class QListBoxItem;
class QalculateExpressionEdit : public KLineEdit {
Q_OBJECT
public:
QalculateExpressionEdit(bool connected_to_main_win, QWidget *parent = 0, const char *name = 0);
virtual ~QalculateExpressionEdit();
QValueVector<ExpressionItem*> matched_items;
bool b_main;
QStringList expression_history;
int expression_history_index;
bool dont_change_index;
QalculateExpressionEditCompletionBox *qalculateCompletionBox;
KCompletion *qalculateCompletion;
virtual bool eventFilter(QObject *o, QEvent *ev);
void keyPressEvent(QKeyEvent *e);
public slots:
void onTextChanged(const QString&);
void addToHistory(const QString&);
void wrapSelection();
void makeCompletion(const QString&);
void insertCompletion(QListBoxItem *li);
void updateCompletion();
void setAfterCompletionPosition();
void cancelCompletion(const QString &str);
void setCompletedItems();
void enableCompletion();
void disableCompletion();
bool completionEnabled() const;
signals:
void cursorMoved();
protected:
virtual QPopupMenu *createPopupMenu();
virtual void timerEvent(QTimerEvent*);
int cstart, cend, cpos_ac, prev_position, pos_timer;
QString completed_text;
int pos_before_completion;
};
class QalculateExpressionEditCompletionBox : public KCompletionBox {
Q_OBJECT
public:
QalculateExpressionEditCompletionBox(QWidget *parent, const char *name = 0);
virtual ~QalculateExpressionEditCompletionBox();
void insertItemList(const QValueVector<ExpressionItem*>& list, int index = -1);
public slots:
void setItems(const QValueVector<ExpressionItem*>& items);
protected:
void hideEvent(QHideEvent*);
signals:
void hidden();
};
#endif

@ -0,0 +1,537 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculatefunctionsdialog.h"
#include "qalculate_kde_utils.h"
#include "qalculateeditfunctiondialog.h"
#include <kpushbutton.h>
#include <qsplitter.h>
#include <qvbox.h>
#include <qhbox.h>
#include <klistview.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <qlayout.h>
#include <ktextbrowser.h>
#include <kapplication.h>
#include <kstdguiitem.h>
extern tree_struct function_cats;
extern vector<void*> ia_functions;
extern PrintOptions printops;
QalculateFunctionsDialog::QalculateFunctionsDialog(QWidget *parent, const char *name) : KDialog(parent, name, false) {
function_edit_dialog = NULL;
selected_category = "";
selected_function = NULL;
QHBoxLayout *layout = new QHBoxLayout(this, marginHint(), spacingHint());
setCaption(i18n("Functions"));
QVBoxLayout *leftLayout = new QVBoxLayout(layout, spacingHint());
QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
leftLayout->addWidget(splitter);
categoryView = new KListView(splitter);
categoryView->addColumn(i18n("Category"));
categoryView->setRootIsDecorated(false);
functionView = new KListView(splitter);
functionView->addColumn(i18n("Function Name"));
functionView->setRootIsDecorated(false);
descriptionBrowser = new KTextBrowser(this);
leftLayout->addWidget(descriptionBrowser);
QVBoxLayout *buttonLayout = new QVBoxLayout(layout, spacingHint());
newButton = new QPushButton(i18n("New"), this);
buttonLayout->addWidget(newButton);
editButton = new QPushButton(i18n("Edit"), this);
editButton->setEnabled(false);
buttonLayout->addWidget(editButton);
deleteButton = new QPushButton(i18n("Delete"), this);
deleteButton->setEnabled(false);
buttonLayout->addWidget(deleteButton);
deactivateButton = new QPushButton(i18n("Deactivate"), this);
deactivateButton->setEnabled(false);
buttonLayout->addWidget(deactivateButton);
insertButton = new QPushButton(i18n("Insert"), this);
insertButton->setEnabled(false);
buttonLayout->addWidget(insertButton);
applyButton = new QPushButton(i18n("Apply"), this);
applyButton->setEnabled(false);
buttonLayout->addWidget(applyButton);
buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
helpButton = new KPushButton(KStdGuiItem::help(), this);
buttonLayout->addWidget(helpButton);
buttonClose = new KPushButton(KStdGuiItem::close(), this);
buttonClose->setFocus();
buttonLayout->addWidget(buttonClose);
resize(QSize(675, 475).expandedTo(size()));
connect(buttonClose, SIGNAL(clicked()), this, SLOT(close()));
connect(newButton, SIGNAL(clicked()), this, SLOT(newFunction()));
connect(editButton, SIGNAL(clicked()), this, SLOT(editFunction()));
connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteFunction()));
connect(deactivateButton, SIGNAL(clicked()), this, SLOT(deactivateFunction()));
connect(insertButton, SIGNAL(clicked()), this, SLOT(insertFunction()));
connect(applyButton, SIGNAL(clicked()), this, SLOT(applyFunction()));
connect(functionView, SIGNAL(selectionChanged()), this, SLOT(functionSelected()));
connect(functionView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(functionDoubleClicked(QListViewItem*)));
connect(categoryView, SIGNAL(selectionChanged()), this, SLOT(categorySelected()));
connect(helpButton, SIGNAL(clicked()), this, SLOT(slotHelp()));
}
QalculateFunctionsDialog::~QalculateFunctionsDialog() {
}
void QalculateFunctionsDialog::slotHelp() {
KApplication::kApplication()->invokeHelp("qalculate-managers");
}
void QalculateFunctionsDialog::updateFunctionTree() {
functionItems.clear();
categoryItems.clear();
categoryView->clear();
QListViewItem *i = new KListViewItem(categoryView, i18n("All")), *i2;
categoryItems[i] = i18n("All");
i->setOpen(true);
QString str;
tree_struct *item, *item2;
function_cats.it = function_cats.items.begin();
if(function_cats.it != function_cats.items.end()) {
item = &*function_cats.it;
++function_cats.it;
item->it = item->items.begin();
} else {
item = NULL;
}
str = "";
i2 = i;
while(item) {
str += "/";
str += item->item.c_str();
i = new KListViewItem(i2, item->item.c_str());
i->setOpen(false);
categoryItems[i] = str;
if(str == selected_category) {
categoryView->ensureItemVisible(i);
categoryView->setSelected(i, true);
}
while(item && item->it == item->items.end()) {
int str_i = str.findRev("/");
if(str_i < 0) {
str = "";
} else {
str.truncate(str_i);
}
item = item->parent;
i = i->parent();
i2 = i;
}
if(item) {
item2 = &*item->it;
if(item->it == item->items.begin())
i2 = i;
++item->it;
item = item2;
item->it = item->items.begin();
}
}
if(!function_cats.objects.empty()) {
//add "Uncategorized" category if there are functions without category
i = new KListViewItem(categoryView, i18n("Uncategorized"));
categoryItems[i] = i18n("Uncategorized");
if(selected_category == i18n("Uncategorized")) {
categoryView->ensureItemVisible(i);
categoryView->setSelected(i, true);
}
}
if(!ia_functions.empty()) {
//add "Inactive" category if there are inactive functions
i = new KListViewItem(categoryView, i18n("Inactive"));
categoryItems[i] = i18n("Inactive");
if(selected_category == i18n("Inactive")) {
categoryView->ensureItemVisible(i);
categoryView->setSelected(i, true);
}
}
if(!categoryView->selectedItem()) {
//if no category has been selected (previously selected has been renamed/deleted), select "All"
selected_category = i18n("All");
QListViewItemIterator it(categoryView);
if(it.current())
categoryView->setSelected(it.current(), true);
}
}
#define UPDATE_SELECTED_FUNCTION QListViewItem *i = functionView->selectedItem(); if(!i) return; selected_function = functionItems[i]; if(!selected_function) return;
#define CHECK_IF_FUNCTION_STILL_THERE if(!CALCULATOR->stillHasFunction(selected_function)) {KMessageBox::error(this, i18n("Function does not exist anymore.")); emit functionsChanged(); return;}
void QalculateFunctionsDialog::insertFunction() {
UPDATE_SELECTED_FUNCTION
CHECK_IF_FUNCTION_STILL_THERE
emit insertRequest(selected_function);
}
void QalculateFunctionsDialog::applyFunction() {
UPDATE_SELECTED_FUNCTION
CHECK_IF_FUNCTION_STILL_THERE
emit applyRequest(selected_function);
}
void QalculateFunctionsDialog::deactivateFunction() {
UPDATE_SELECTED_FUNCTION
CHECK_IF_FUNCTION_STILL_THERE
selected_function->setActive(!selected_function->isActive());
emit functionsChanged();
}
void QalculateFunctionsDialog::deleteFunction() {
UPDATE_SELECTED_FUNCTION
CHECK_IF_FUNCTION_STILL_THERE
if(selected_function->isLocal()) {
//ensure that all references are removed in Calculator
selected_function->destroy();
//update menus and trees
emit functionsChanged();
}
}
void QalculateFunctionsDialog::editFunction() {
UPDATE_SELECTED_FUNCTION
CHECK_IF_FUNCTION_STILL_THERE
if(!function_edit_dialog) {
function_edit_dialog = new QalculateEditFunctionDialog(this);
}
MathFunction *f = function_edit_dialog->editFunction(QString::null, selected_function);
if(f) {
selected_function = f;
if(!f->isActive()) {
selected_category = i18n("Inactive");
} else if(f->category().empty()) {
selected_category = i18n("Uncategorized");
} else {
selected_category = "/";
selected_category += f->category().c_str();
}
emit functionsChanged();
}
}
void QalculateFunctionsDialog::newFunction() {
if(!function_edit_dialog) {
function_edit_dialog = new QalculateEditFunctionDialog(this);
}
MathFunction *f = NULL;
if(selected_category.isEmpty() || selected_category[0] != '/') {
f = function_edit_dialog->editFunction();
} else {
QString str = selected_category;
str.remove(0, 1);
f = function_edit_dialog->editFunction(str);
}
if(f) {
selected_function = f;
if(!f->isActive()) {
selected_category = i18n("Inactive");
} else if(f->category().empty()) {
selected_category = i18n("Uncategorized");
} else {
selected_category = "/";
selected_category += f->category().c_str();
}
emit functionsChanged();
}
}
void QalculateFunctionsDialog::functionDoubleClicked(QListViewItem*i) {
selected_function = functionItems[i];
if(!selected_function)
return;
CHECK_IF_FUNCTION_STILL_THERE
if(!function_edit_dialog) {
function_edit_dialog = new QalculateEditFunctionDialog(this);
}
MathFunction *f = function_edit_dialog->editFunction(QString::null, selected_function);
if(f) {
selected_function = f;
if(!f->isActive()) {
selected_category = i18n("Inactive");
} else if(f->category().empty()) {
selected_category = i18n("Uncategorized");
} else {
selected_category = "/";
selected_category += f->category().c_str();
}
emit functionsChanged();
}
}
void QalculateFunctionsDialog::functionSelected() {
QListViewItem *selected = functionView->selectedItem();
if(selected) {
MathFunction *f = functionItems[selected];
if(!CALCULATOR->stillHasFunction(f)) {
KMessageBox::error(this, i18n("Function does not exist anymore."));
selected_function = NULL;
emit functionsChanged();
return;
}
//remember selection
selected_function = f;
editButton->setEnabled(true);
insertButton->setEnabled(f->isActive());
applyButton->setEnabled(f->isActive() && f->minargs() <= 1);
deleteButton->setEnabled(f->isLocal());
deactivateButton->setEnabled(true);
if(f->isActive()) {
deactivateButton->setText(i18n("Deactivate"));
} else {
deactivateButton->setText(i18n("Activate"));
}
Argument *arg;
Argument default_arg;
QString str, str2;
const ExpressionName *ename = &f->preferredName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) descriptionBrowser);
str += "<i><b>";
str += ename->name.c_str();
str += "</b>";
int iargs = f->maxargs();
if(iargs < 0) {
iargs = f->minargs() + 1;
}
str += "(";
if(iargs != 0) {
for(int i2 = 1; i2 <= iargs; i2++) {
if(i2 > f->minargs()) {
str += "[";
}
if(i2 > 1) {
str += CALCULATOR->getComma().c_str();
str += " ";
}
arg = f->getArgumentDefinition(i2);
if(arg && !arg->name().empty()) {
str += arg->name().c_str();
} else {
str += i18n("argument");
str += " ";
str += QString::number(i2);
}
if(i2 > f->minargs()) {
str += "]";
}
}
if(f->maxargs() < 0) {
str += CALCULATOR->getComma().c_str();
str += " ...";
}
}
str += ")";
for(size_t i2 = 1; i2 <= f->countNames(); i2++) {
if(&f->getName(i2) != ename) {
str += "<br>";
str += f->getName(i2).name.c_str();
}
}
str += "</i>";
str += "<br>";
if(f->subtype() == SUBTYPE_DATA_SET) {
str += "<br>";
str2.sprintf(i18n("Retrieves data from the %s data set for a given object and property. If \"info\" is typed as property, a dialog window will pop up with all properties of the object."), f->title().c_str());
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
str += "<br>";
}
if(!f->description().empty()) {
str += "<br>";
str2 = f->description().c_str();
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
str += "<br>";
}
if(f->subtype() == SUBTYPE_DATA_SET && !((DataSet*) f)->copyright().empty()) {
str += "<br>";
str2 = ((DataSet*) f)->copyright().c_str();
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
str += "<br>";
}
if(iargs) {
str += "<br><b>";
str += i18n("Arguments");
str += "</b><br>";
for(int i2 = 1; i2 <= iargs; i2++) {
arg = f->getArgumentDefinition(i2);
if(arg && !arg->name().empty()) {
str += arg->name().c_str();
} else {
str += QString::number(i2);
}
str += ": <i>";
if(arg) {
str2= arg->printlong().c_str();
} else {
str2= default_arg.printlong().c_str();
}
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
if(i2 > f->minargs()) {
str += " (";
//optional argument
str += i18n("optional");
if(!f->getDefaultValue(i2).empty()) {
str += ", ";
//argument default, in description
str += i18n("default: ");
str += f->getDefaultValue(i2).c_str();
}
str += ")";
}
str += "</i><br>";
}
}
if(!f->condition().empty()) {
str += "<br>";
str += i18n("Requirement");
str += ": ";
str2 = f->printCondition().c_str();
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
str += "<br>";
}
if(f->subtype() == SUBTYPE_DATA_SET) {
DataSet *ds = (DataSet*) f;
str += "<br><b>";
str += i18n("Properties");
str += "</b><br>";
DataPropertyIter it;
DataProperty *dp = ds->getFirstProperty(&it);
while(dp) {
if(!dp->isHidden()) {
if(!dp->title(false).empty()) {
str2 = dp->title().c_str();
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
str += ": ";
}
for(size_t i = 1; i <= dp->countNames(); i++) {
if(i > 1) str += ", ";
str += dp->getName(i).c_str();
}
if(dp->isKey()) {
str += " (";
str += i18n("key");
str += ")";
}
str += "<br>";
if(!dp->description().empty()) {
str += "<i>";
str2 = dp->description().c_str();
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
str += "</i><br>";
}
}
dp = ds->getNextProperty(&it);
}
}
str.replace("\n", "<br>");
descriptionBrowser->setText(str);
} else {
editButton->setEnabled(false);
insertButton->setEnabled(false);
applyButton->setEnabled(false);
deleteButton->setEnabled(false);
deactivateButton->setEnabled(false);
selected_function = NULL;
descriptionBrowser->clear();
}
}
void QalculateFunctionsDialog::addFunctionTreeItem(MathFunction *f) {
QListViewItem *i = new KListViewItem(functionView, f->title(true).c_str());
functionItems[i] = f;
if(f == selected_function) {
functionView->setSelected(i, true);
}
}
void QalculateFunctionsDialog::categorySelected() {
QListViewItem *selected = categoryView->selectedItem();
bool no_cat = false, b_all = false, b_inactive = false;
functionView->clear();
functionItems.clear();
if(!selected) {
selected_category = "";
functionSelected();
return;
}
selected_category = categoryItems[selected];
if(selected_category == i18n("All")) {
b_all = true;
} else if(selected_category == i18n("Uncategorized")) {
no_cat = true;
} else if(selected_category == i18n("Inactive")) {
b_inactive = true;
}
if(!b_all && !no_cat && !b_inactive && selected_category[0] == '/') {
string str = selected_category.ascii();
str.erase(str.begin());
for(size_t i = 0; i < CALCULATOR->functions.size(); i++) {
if(CALCULATOR->functions[i]->isActive() && CALCULATOR->functions[i]->category().substr(0, selected_category.length() - 1) == str) {
addFunctionTreeItem(CALCULATOR->functions[i]);
}
}
} else {
string str = selected_category.ascii();
for(size_t i = 0; i < CALCULATOR->functions.size(); i++) {
if((b_inactive && !CALCULATOR->functions[i]->isActive()) || (CALCULATOR->functions[i]->isActive() && (b_all || (no_cat && CALCULATOR->functions[i]->category().empty()) || (!b_inactive && CALCULATOR->functions[i]->category() == str)))) {
addFunctionTreeItem(CALCULATOR->functions[i]);
}
}
}
if(!selected_function || !functionView->selectedItem()) {
QListViewItemIterator it(functionView);
if(it.current())
functionView->setSelected(it.current(), true);
}
}
#include "qalculatefunctionsdialog.moc"

@ -0,0 +1,89 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEFUNCTIONSDIALOG_H
#define QALCULATEFUNCTIONSDIALOG_H
#include <kdialog.h>
#include <qmap.h>
class MathFunction;
class QalculateEditFunctionDialog;
class KListView;
class QListViewItem;
class QPushButton;
class KTextBrowser;
/**
@author Niklas Knutsson
*/
class QalculateFunctionsDialog : public KDialog {
Q_OBJECT
public:
QalculateFunctionsDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateFunctionsDialog();
QalculateEditFunctionDialog *function_edit_dialog;
QString selected_category;
MathFunction *selected_function;
void addFunctionTreeItem(MathFunction *f);
QMap<QListViewItem*, MathFunction*> functionItems;
QMap<QListViewItem*, QString> categoryItems;
KListView *categoryView;
KListView *functionView;
QPushButton *newButton;
QPushButton *editButton;
QPushButton *deleteButton;
QPushButton *deactivateButton;
QPushButton *insertButton;
QPushButton *applyButton;
QPushButton *helpButton;
QPushButton *buttonClose;
KTextBrowser *descriptionBrowser;
public slots:
void updateFunctionTree();
void functionDoubleClicked(QListViewItem*);
void functionSelected();
void categorySelected();
void insertFunction();
void applyFunction();
void deactivateFunction();
void deleteFunction();
void editFunction();
void newFunction();
protected slots:
void slotHelp();
signals:
void functionsChanged();
void insertRequest(MathFunction*);
void applyRequest(MathFunction*);
};
#endif

@ -0,0 +1,216 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateimportcsvdialog.h"
#include "qalculate_kde_utils.h"
#include <qlayout.h>
#include <kurlrequester.h>
#include <klineedit.h>
#include <qlabel.h>
#include <qradiobutton.h>
#include <qcheckbox.h>
#include <qpushbutton.h>
#include <kcombobox.h>
#include <qspinbox.h>
#include <qbuttongroup.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <kapplication.h>
extern tree_struct variable_cats;
QalculateImportCSVDialog::QalculateImportCSVDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Import CSV File"), Ok | Cancel | Help, Ok, true) {
setMainWidget(new QWidget(this));
QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
grid->addWidget(new QLabel(i18n("File:"), mainWidget()), 0, 0);
fileEdit = new KURLRequester(mainWidget());
fileEdit->setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly);
fileEdit->setCaption(i18n("Import CSV File"));
grid->addWidget(fileEdit, 0, 1);
grid->addWidget(new QLabel(i18n("Import as:"), mainWidget()), 1, 0);
QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addLayout(hbox, 1, 1);
QButtonGroup *group = new QButtonGroup();
matrixButton = new QRadioButton(i18n("Matrix"), mainWidget());
group->insert(matrixButton, 0);
hbox->addWidget(matrixButton);
matrixButton->setChecked(true);
vectorsButton = new QRadioButton(i18n("Vectors"), mainWidget());
group->insert(vectorsButton, 1);
hbox->addWidget(vectorsButton);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 2, 0);
nameEdit = new KLineEdit(mainWidget());
grid->addWidget(nameEdit, 2, 1);
grid->addWidget(new QLabel(i18n("Descriptive name:"), mainWidget()), 3, 0);
titleEdit = new KLineEdit(mainWidget());
grid->addWidget(titleEdit, 3, 1);
grid->addWidget(new QLabel(i18n("Category:"), mainWidget()), 4, 0);
categoryCombo = new KComboBox(mainWidget());
categoryCombo->setMaximumWidth(250);
categoryCombo->setEditable(true);
grid->addWidget(categoryCombo, 4, 1);
grid->addWidget(new QLabel(i18n("First row:"), mainWidget()), 5, 0);
firstRowBox = new QSpinBox(1, 1000, 1, mainWidget());
grid->addWidget(firstRowBox, 5, 1);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 6, 6, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
includesHeadingsButton = new QCheckBox(i18n("Includes headings"), mainWidget());
includesHeadingsButton->setChecked(true);
hbox->addWidget(includesHeadingsButton);
grid->addWidget(new QLabel(i18n("Delimiter:"), mainWidget()), 7, 0);
delimiterCombo = new KComboBox(mainWidget());
delimiterCombo->setMaximumWidth(250);
delimiterCombo->insertItem(i18n("Comma"));
delimiterCombo->insertItem(i18n("Tabulator"));
delimiterCombo->insertItem(i18n("Semicolon"));
delimiterCombo->insertItem(i18n("Space"));
delimiterCombo->insertItem(i18n("Other"));
delimiterCombo->setEditable(false);
grid->addWidget(delimiterCombo, 7, 1);
otherDelimiterEdit = new KLineEdit(mainWidget());
grid->addWidget(otherDelimiterEdit, 8, 1);
otherDelimiterEdit->setEnabled(false);
connect(delimiterCombo, SIGNAL(activated(int)), this, SLOT(delimiterChanged(int)));
connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&)));
}
QalculateImportCSVDialog::~QalculateImportCSVDialog() {
}
void QalculateImportCSVDialog::slotHelp() {
KApplication::kApplication()->invokeHelp("qalculate-import-export-csv");
}
void QalculateImportCSVDialog::delimiterChanged(int i) {
otherDelimiterEdit->setEnabled(i == 4);
}
void QalculateImportCSVDialog::slotOk() {
QString str = fileEdit->url().stripWhiteSpace();
if(str.isEmpty()) {
//no name -- open dialog again
fileEdit->setFocus();
KMessageBox::error(this, i18n("No file name entered."));
return;
}
string delimiter = "";
switch(delimiterCombo->currentItem()) {
case 0: {
delimiter = ",";
break;
}
case 1: {
delimiter = "\t";
break;
}
case 2: {
delimiter = ";";
break;
}
case 3: {
delimiter = " ";
break;
}
case 4: {
delimiter = otherDelimiterEdit->text().ascii();
break;
}
}
if(delimiter.empty()) {
//no delimiter -- open dialog again
otherDelimiterEdit->setFocus();
KMessageBox::error(this, i18n("No delimiter selected."));
return;
}
if(!CALCULATOR->importCSV(str.ascii(), firstRowBox->value(), includesHeadingsButton->isChecked(), delimiter, matrixButton->isChecked(), nameEdit->text().ascii(), titleEdit->text().ascii(), categoryCombo->lineEdit()->text().ascii())) {
KMessageBox::error(this, i18n("An error occured when importing the CSV file."));
reject();
}
accept();
}
bool QalculateImportCSVDialog::importCSVFile() {
fileEdit->setFocus();
nameEdit->clear();
fileEdit->clear();
titleEdit->clear();
//QStringList cats;
QString catstr;
categoryCombo->clear();
tree_struct *item, *item2;
variable_cats.it = variable_cats.items.begin();
if(variable_cats.it != variable_cats.items.end()) {
item = &*variable_cats.it;
++variable_cats.it;
item->it = item->items.begin();
} else {
item = NULL;
}
catstr = "";
while(item) {
if(!catstr.isEmpty()) catstr += "/";
catstr += item->item.c_str();
categoryCombo->insertItem(catstr);
while(item && item->it == item->items.end()) {
int str_i = catstr.findRev("/");
if(str_i < 0) {
catstr = "";
} else {
catstr.truncate(str_i);
}
item = item->parent;
}
if(item) {
item2 = &*item->it;
++item->it;
item = item2;
item->it = item->items.begin();
}
}
categoryCombo->lineEdit()->clear();
if(exec() == QDialog::Accepted) {
return true;
}
return false;
}
void QalculateImportCSVDialog::nameChanged(const QString &name) {
if(name.isNull()) return;
if(!CALCULATOR->variableNameIsValid(name.ascii())) {
nameEdit->blockSignals(true);
nameEdit->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str());
nameEdit->blockSignals(false);
}
}
#include "qalculateimportcsvdialog.moc"

@ -0,0 +1,65 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEIMPORTCSVDIALOG_H
#define QALCULATEIMPORTCSVDIALOG_H
#include <kdialogbase.h>
class KLineEdit;
class KComboBox;
class QSpinBox;
class QCheckBox;
class QRadioButton;
class KURLRequester;
/**
@author Niklas Knutsson
*/
class QalculateImportCSVDialog : public KDialogBase {
Q_OBJECT
public:
QalculateImportCSVDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateImportCSVDialog();
KLineEdit *nameEdit, *titleEdit, *otherDelimiterEdit;
KComboBox *categoryCombo, *delimiterCombo;
QSpinBox *firstRowBox;
QCheckBox *includesHeadingsButton;
QRadioButton *matrixButton, *vectorsButton;
KURLRequester *fileEdit;
bool importCSVFile();
public slots:
void delimiterChanged(int);
void nameChanged(const QString&);
protected slots:
void slotHelp();
void slotOk();
};
#endif

@ -0,0 +1,404 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateinsertfunctiondialog.h"
#include "qalculate_kde_utils.h"
#include <qvbox.h>
#include <kactivelabel.h>
#include <klineedit.h>
#include <qlabel.h>
#include <qgrid.h>
#include <qhbox.h>
#include <klocale.h>
#include <qspinbox.h>
#include <kcombobox.h>
#include <qhbuttongroup.h>
#include <qradiobutton.h>
#include <qstring.h>
#include <qpushbutton.h>
#include <kdatepicker.h>
#include <kfiledialog.h>
#include <kdeversion.h>
#include <kstdguiitem.h>
#include "buttonwithindexsignal.h"
#include "qalculateinsertmatrixvectordialog.h"
extern QWidget *expressionWidget;
extern PrintOptions printops;
extern EvaluationOptions evalops;
QalculateInsertFunctionDialog::QalculateInsertFunctionDialog(MathFunction *f, QWidget *parent, const QString &selected_text, const char *name) : KDialogBase(parent, name, true, f->title(true).c_str(), Ok|Apply|Cancel, Ok) {
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
setButtonOKText(i18n("Insert"));
setButtonApplyText(i18n("Execute"));
#else
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 3
setButtonOK(KGuiItem(i18n("Insert")));
#else
setButtonOK(KStdGuiItem::insert());
#endif
setButtonApply(KGuiItem(i18n("Execute")));
#endif
mathFunction = f;
QVBox *box = makeVBoxMainWidget();
box->setSpacing(12);
QString titlestr = "<font size=\"5\">";
titlestr += mathFunction->title(true).c_str();
titlestr += "</font>";
new QLabel(titlestr, box);
int args = 0;
bool has_vector = false;
if(mathFunction->args() > 0) {
args = mathFunction->args();
} else if(mathFunction->minargs() > 0) {
args = mathFunction->minargs() + 1;
has_vector = true;
} else {
args = 1;
has_vector = true;
}
QGrid *table = new QGrid(3, box);
table->setSpacing(6);
table->setMargin(12);
table->setFrameStyle(QFrame::Sunken | QFrame::GroupBoxPanel);
label.resize(args);
entry.resize(args);
type_label.resize(args);
QString argstr, typestr, defstr, argtype;
//create argument entries
Argument *arg;
for(int i = 0; i < args; i++) {
arg = mathFunction->getArgumentDefinition(i + 1);
if(!arg || arg->name().empty()) {
if(args == 1) {
argstr = i18n("Value:");
} else {
argstr = i18n("Argument");
argstr += " ";
argstr += QString::number(i + 1);
argstr += ":";
}
} else {
argstr = arg->name().c_str();
argstr += ":";
}
typestr = "";
argtype = "";
defstr = mathFunction->getDefaultValue(i + 1).c_str();
if(arg && (arg->suggestsQuotes() || arg->type() == ARGUMENT_TYPE_TEXT) && defstr.length() >= 2 && defstr[0] == '\"' && defstr[defstr.length() - 1] == '\"') {
defstr.remove(0, 1);
defstr.truncate(defstr.length() - 1);
}
label[i] = new QLabel(argstr, table);
if(arg) {
switch(arg->type()) {
case ARGUMENT_TYPE_INTEGER: {
IntegerArgument *iarg = (IntegerArgument*) arg;
int min = -1000000, max = 1000000;
if(iarg->min()) {
min = iarg->min()->intValue();
}
if(iarg->max()) {
max = iarg->max()->intValue();
}
QSpinBox *qsp = new QSpinBox(min, max, 1, table);
entry[i] = qsp;
qsp->setButtonSymbols(QSpinBox::PlusMinus);
int selected_value = 0;
bool convok = false;
if(i == 0 && !selected_text.isEmpty()) {
selected_value = selected_text.toInt(&convok);
}
if(convok && selected_value >= min && selected_value <= max) {
qsp->setValue(selected_value);
} else if(!mathFunction->getDefaultValue(i + 1).empty()) {
qsp->setValue(QString(mathFunction->getDefaultValue(i + 1).c_str()).toInt());
} else if(!arg->zeroForbidden() && min <= 0 && max >= 0) {
qsp->setValue(0);
} else {
if(max < 0) {
qsp->setValue(max);
} else if(min <= 1) {
qsp->setValue(1);
} else {
qsp->setValue(min);
}
}
break;
}
case ARGUMENT_TYPE_BOOLEAN: {
QHButtonGroup *bg = new QHButtonGroup(table);
entry[i] = bg;
bg->setFrameStyle(QFrame::Plain | QFrame::NoFrame);
bg->setMargin(0);
bg->setRadioButtonExclusive(TRUE);
bg->insert(new QRadioButton(i18n("True"), bg), 1);
bg->insert(new QRadioButton(i18n("False"), bg), 0);
QString str = selected_text.stripWhiteSpace();
if(i == 0 && str == "1") {
bg->setButton(1);
} else if(i == 0 && str == "0") {
bg->setButton(0);
} else if(defstr == "1") {
bg->setButton(1);
} else {
bg->setButton(0);
}
break;
}
case ARGUMENT_TYPE_DATA_PROPERTY: {
if(mathFunction->subtype() == SUBTYPE_DATA_SET) {
KComboBox *cb = new KComboBox(table);
entry[i] = cb;
DataPropertyIter it;
DataSet *ds = (DataSet*) mathFunction;
DataProperty *dp = ds->getFirstProperty(&it);
bool active_set = false;
while(dp) {
if(!dp->isHidden()) {
cb->insertItem(dp->title().c_str());
if(!active_set && defstr == dp->getName().c_str()) {
cb->setCurrentItem(cb->count() - 1);
active_set = true;
}
}
dp = ds->getNextProperty(&it);
}
cb->insertItem(i18n("Info"));
if(!active_set) {
cb->setCurrentItem(cb->count() - 1);
}
break;
}
}
default: {
if(i >= mathFunction->minargs() && !has_vector) {
typestr = "(";
typestr += i18n("optional");
}
argtype = arg->print().c_str();
if(typestr.isEmpty()) {
typestr = "(";
} else if(!argtype.isEmpty()) {
typestr += " ";
}
if(!argtype.isEmpty()) {
typestr += argtype;
}
typestr += ")";
if(typestr.length() == 2) {
typestr = "";
}
entry[i] = new KLineEdit(table);
if(i == 0 && !selected_text.isEmpty()) {
((KLineEdit*) entry[i])->setText(selected_text);
} else {
((KLineEdit*) entry[i])->setText(defstr);
}
}
}
} else {
entry[i] = new KLineEdit(table);
if(i == 0 && !selected_text.isEmpty()) {
((KLineEdit*) entry[i])->setText(selected_text);
} else {
((KLineEdit*) entry[i])->setText(defstr);
}
}
if(typestr.isEmpty() && i >= mathFunction->minargs() && !has_vector) {
typestr = "(";
typestr += i18n("optional");
typestr += ")";
}
if(arg) {
switch(arg->type()) {
case ARGUMENT_TYPE_DATE: {
typestr.remove(0, 1);
typestr.remove(typestr.length() - 1, 1);
type_label[i] = new ButtonWithIndexSignal(typestr, i, table);
QObject::connect(type_label[i], SIGNAL(clickedWithIndex(int)), this, SLOT(selectDate(int)));
break;
}
case ARGUMENT_TYPE_MATRIX: {
typestr.remove(0, 1);
typestr.remove(typestr.length() - 1, 1);
type_label[i] = new ButtonWithIndexSignal(typestr, i, table);
QObject::connect(type_label[i], SIGNAL(clickedWithIndex(int)), this, SLOT(insertMatrix(int)));
break;
}
case ARGUMENT_TYPE_VECTOR: {
typestr.remove(0, 1);
typestr.remove(typestr.length() - 1, 1);
type_label[i] = new ButtonWithIndexSignal(typestr, i, table);
QObject::connect(type_label[i], SIGNAL(clickedWithIndex(int)), this, SLOT(insertVector(int)));
break;
}
case ARGUMENT_TYPE_FILE: {
typestr.remove(0, 1);
typestr.remove(typestr.length() - 1, 1);
type_label[i] = new ButtonWithIndexSignal(typestr, i, table);
QObject::connect(type_label[i], SIGNAL(clickedWithIndex(int)), this, SLOT(selectFile(int)));
break;
}
default: {
type_label[i] = new QLabel(typestr, table);
}
}
} else {
type_label[i] = new QLabel(typestr, table);
}
if(i == 0) entry[0]->setFocus();
}
//display function description
if(!mathFunction->description().empty()) {
QString str = mathFunction->description().c_str();
str.replace("<", "&lt;");
str.replace(">", "&gt;");
str.replace("\n", "<br>");
KActiveLabel *descrLabel = new KActiveLabel(str, box);
descrLabel->setAlignment(Qt::AlignJustify);
enableButtonSeparator(true);
}
}
QalculateInsertFunctionDialog::~QalculateInsertFunctionDialog() {
}
QString QalculateInsertFunctionDialog::functionExpression() {
QString str = mathFunction->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionWidget).name.c_str(), str2;
str += "(";
int args = 0;
if(mathFunction->args() > 0) {
args = mathFunction->args();
} else if(mathFunction->minargs() > 0) {
args = mathFunction->minargs() + 1;
} else {
args = 1;
}
for(int i = 0; i < args; i++) {
if(mathFunction->getArgumentDefinition(i + 1) && mathFunction->getArgumentDefinition(i + 1)->type() == ARGUMENT_TYPE_BOOLEAN) {
if(((QButtonGroup*) entry[i])->id(((QButtonGroup*) entry[i])->selected()) == 1) {
str2 = "1";
} else {
str2 = "0";
}
} else if(mathFunction->getArgumentDefinition(i + 1) && mathFunction->getArgumentDefinition(i + 1)->type() == ARGUMENT_TYPE_INTEGER) {
str2 = ((QSpinBox*) entry[i])->text();
} else if(mathFunction->subtype() == SUBTYPE_DATA_SET && mathFunction->getArgumentDefinition(i + 1) && mathFunction->getArgumentDefinition(i + 1)->type() == ARGUMENT_TYPE_DATA_PROPERTY) {
int index = ((KComboBox*) entry[i])->currentItem();
DataPropertyIter it;
DataSet *ds = (DataSet*) mathFunction;
DataProperty *dp = ds->getFirstProperty(&it);
while(dp) {
if(!dp->isHidden()) {
if(index <= 0) break;
index--;
}
dp = ds->getNextProperty(&it);
}
if(dp) {
str2 = dp->getName().c_str();
} else {
str2 = "info";
}
} else {
str2 = ((KLineEdit*) entry[i])->text();
}
//if the minimum number of function arguments have been filled, do not add anymore if entry is empty
if(i >= mathFunction->minargs()) {
str2 = str2.stripWhiteSpace();
}
if((i < mathFunction->minargs() || !str2.isEmpty()) && mathFunction->getArgumentDefinition(i + 1) && (mathFunction->getArgumentDefinition(i + 1)->suggestsQuotes() || (mathFunction->getArgumentDefinition(i + 1)->type() == ARGUMENT_TYPE_TEXT && str2.find(CALCULATOR->getComma().c_str()) >= 0))) {
if(str2.length() < 1 || (str2[0] != '\"' && str[0] != '\'')) {
str2.insert(0, "\"");
str2 += "\"";
}
}
if(i > 0) {
str += CALCULATOR->getComma().c_str();
str += " ";
}
str += str2;
}
str += ")";
return str;
}
void QalculateInsertFunctionDialog::slotOk() {
accept();
}
void QalculateInsertFunctionDialog::slotApply() {
done(100);
}
void QalculateInsertFunctionDialog::selectDate(int index) {
KDialogBase *dialog = new KDialogBase(this, 0, true, i18n("Date"), Ok|Cancel);
KDatePicker *datePicker;
QDate date(QDate::fromString(((KLineEdit*) entry[index])->text(), Qt::ISODate));
if(date.isValid()) datePicker = new KDatePicker(dialog->makeVBoxMainWidget(), date);
else datePicker = new KDatePicker(dialog->makeVBoxMainWidget());
if(dialog->exec() == QDialog::Accepted) {
((KLineEdit*) entry[index])->setText(datePicker->date().toString(Qt::ISODate));
}
dialog->deleteLater();
}
void QalculateInsertFunctionDialog::selectFile(int index) {
QString filename = KFileDialog::getSaveFileName(((KLineEdit*) entry[index])->text(), QString::null, this, i18n("File"));
if(!filename.isEmpty()) {
((KLineEdit*) entry[index])->setText(filename);
}
}
void QalculateInsertFunctionDialog::insertMatrix(int index) {
QalculateInsertMatrixVectorDialog *d = new QalculateInsertMatrixVectorDialog(this);
QString str = ((KLineEdit*) entry[index])->text();
MathStructure mstruct;
if(!str.isEmpty()) {
CALCULATOR->parse(&mstruct, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options));
}
if(mstruct.isVector()) {
str = d->editMatrixVector(&mstruct, false);
} else {
str = d->editMatrixVector(NULL, false);
}
if(!str.isEmpty()) {
((KLineEdit*) entry[index])->setText(str);
}
d->deleteLater();
}
void QalculateInsertFunctionDialog::insertVector(int index) {
QalculateInsertMatrixVectorDialog *d = new QalculateInsertMatrixVectorDialog(this);
QString str = ((KLineEdit*) entry[index])->text();
MathStructure mstruct;
if(!str.isEmpty()) {
CALCULATOR->parse(&mstruct, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options));
}
if(mstruct.isVector()) {
str = d->editMatrixVector(&mstruct, true);
} else {
str = d->editMatrixVector(NULL, true);
}
if(!str.isEmpty()) {
((KLineEdit*) entry[index])->setText(str);
}
d->deleteLater();
}
#include "qalculateinsertfunctiondialog.moc"

@ -0,0 +1,56 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEINSERTFUNCTIONDIALOG_H
#define QALCULATEINSERTFUNCTIONDIALOG_H
#include <kdialogbase.h>
#include <qvaluevector.h>
class MathFunction;
class QalculateInsertFunctionDialog : public KDialogBase {
Q_OBJECT
public:
QalculateInsertFunctionDialog(MathFunction *f, QWidget *parent = 0, const QString &selected_text = QString::null, const char *name = 0);
virtual ~QalculateInsertFunctionDialog();
QString functionExpression();
MathFunction *mathFunction;
QValueVector<QWidget*> label;
QValueVector<QWidget*> entry;
QValueVector<QWidget*> type_label;
protected slots:
void slotOk();
void slotApply();
void selectDate(int);
void selectFile(int);
void insertMatrix(int);
void insertVector(int);
};
#endif

@ -0,0 +1,381 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateinsertmatrixvectordialog.h"
#include "qalculate_kde_utils.h"
#include <qtable.h>
#include <qgrid.h>
#include <klineedit.h>
#include <qpushbutton.h>
#include <kcombobox.h>
#include <qlabel.h>
#include <klocale.h>
#include <qvbox.h>
#include <qhbox.h>
#include <qcheckbox.h>
#include <kmessagebox.h>
#include <qspinbox.h>
#include <qlayout.h>
#include <qbuttongroup.h>
#include <qradiobutton.h>
#include <kapplication.h>
#include <kdeversion.h>
#include <kstdguiitem.h>
extern PrintOptions printops;
class QalculateInsertMatrixTableItem : public QTableItem {
public:
QalculateInsertMatrixTableItem(QTable *table);
QalculateInsertMatrixTableItem(QTable *table, const QString & text);
int alignment() const;
};
class QalculateInsertMatrixTable : public QTable {
public:
QalculateInsertMatrixTable(QWidget *parent = 0, const char *name = 0) : QTable(parent, name) {}
QalculateInsertMatrixTable(int numRows, int numCols, QWidget *parent = 0, const char *name = 0) : QTable(numRows, numCols, parent, name) {}
QWidget *beginEdit(int row, int col, bool replace) {
QWidget *w = QTable::beginEdit(row, col, replace);
((QLineEdit*) w)->selectAll();
return w;
}
};
QalculateInsertMatrixVectorDialog::QalculateInsertMatrixVectorDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Variable"), Ok | Cancel | User1, Ok, true, KGuiItem(i18n("Insert Selection"))) {
setMainWidget(new QWidget(this));
QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint());
grid->addWidget(new QLabel(i18n("Rows:"), mainWidget()), 0, 0);
rowsBox = new QSpinBox(1, 1000, 1, mainWidget());
grid->addWidget(rowsBox, 0, 1);
grid->addWidget(new QLabel(i18n("Columns:"), mainWidget()), 1, 0);
columnsBox = new QSpinBox(1, 1000, 1, mainWidget());
grid->addWidget(columnsBox, 1, 1);
QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 2, 2, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
QButtonGroup *group = new QButtonGroup();
matrixButton = new QRadioButton(i18n("Matrix"), mainWidget());
group->insert(matrixButton, 0);
hbox->addWidget(matrixButton);
vectorButton = new QRadioButton(i18n("Vector"), mainWidget());
group->insert(vectorButton, 1);
hbox->addWidget(vectorButton);
elementsLabel = new QLabel(i18n("Elements:"), mainWidget());
grid->addMultiCellWidget(elementsLabel, 3, 3, 0, 1);
elementsTable = new QalculateInsertMatrixTable(0, 0, mainWidget());
grid->addMultiCellWidget(elementsTable, 4, 4, 0, 1);
elementsTable->setSelectionMode(QTable::Single);
insertSelectionButton = actionButton(User1);
onSelectionChanged();
connect(insertSelectionButton, SIGNAL(clicked()), this, SLOT(insertSelection()));
connect(elementsTable, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
connect(rowsBox, SIGNAL(valueChanged(int)), this, SLOT(rowsChanged(int)));
connect(columnsBox, SIGNAL(valueChanged(int)), this, SLOT(columnsChanged(int)));
connect(group, SIGNAL(clicked(int)), this, SLOT(typeChanged(int)));
}
QalculateInsertMatrixVectorDialog::~QalculateInsertMatrixVectorDialog() {}
void QalculateInsertMatrixVectorDialog::onSelectionChanged() {
insertSelectionButton->setEnabled(elementsTable->currentSelection() >= 0);
}
void QalculateInsertMatrixVectorDialog::typeChanged(int i) {
if(i == 0) {
elementsLabel->setText(i18n("Elements:"));
bool b = true;
for(int index_r = elementsTable->numRows() - 1; index_r >= 0 && b; index_r--) {
for(int index_c = elementsTable->numCols() - 1; index_c >= 0; index_c--) {
if(elementsTable->text(index_r, index_c).isEmpty()) {
elementsTable->setText(index_r, index_c, "0");
} else {
b = false;
break;
}
}
}
} else {
elementsLabel->setText(i18n("Elements (in horizontal order):"));
}
}
void QalculateInsertMatrixVectorDialog::rowsChanged(int i) {
int r = elementsTable->numRows();
elementsTable->setNumRows(i);
bool b = matrixButton->isChecked();
for(int index_r = r; index_r < i; index_r++) {
for(int index_c = 0; index_c < elementsTable->numCols(); index_c++) {
if(b) elementsTable->setItem(index_r, index_c, new QalculateInsertMatrixTableItem(elementsTable, "0"));
else elementsTable->setItem(index_r, index_c, new QalculateInsertMatrixTableItem(elementsTable));
}
}
}
void QalculateInsertMatrixVectorDialog::columnsChanged(int i) {
int c = elementsTable->numCols();
elementsTable->setNumCols(i);
bool b = matrixButton->isChecked();
for(int index_r = 0; index_r < elementsTable->numRows(); index_r++) {
for(int index_c = c; index_c < i; index_c++) {
if(b) elementsTable->setItem(index_r, index_c, new QalculateInsertMatrixTableItem(elementsTable, "0"));
else elementsTable->setItem(index_r, index_c, new QalculateInsertMatrixTableItem(elementsTable));
}
}
}
QString QalculateInsertMatrixVectorDialog::newVector() {
return editMatrixVector(NULL, true);
}
QString QalculateInsertMatrixVectorDialog::newMatrix() {
return editMatrixVector(NULL, false);
}
void QalculateInsertMatrixVectorDialog::slotOk() {
int r = rowsBox->value();
int c = columnsBox->value();
if(vectorButton->isChecked()) {
bool b = false;
matrixstr = "[";
for(int index_r = 0; index_r < r; index_r++) {
for(int index_c = 0; index_c < c; index_c++) {
if(!elementsTable->text(index_r, index_c).isEmpty()) {
QString str2 = elementsTable->text(index_r, index_c).stripWhiteSpace();
if(!str2.isEmpty()) {
if(b) {
matrixstr += CALCULATOR->getComma();
matrixstr += " ";
} else {
b = true;
}
matrixstr += str2;
}
}
}
}
matrixstr += "]";
} else {
matrixstr = "[";
bool b1 = false;
for(int index_r = 0; index_r < r; index_r++) {
if(b1) {
matrixstr += CALCULATOR->getComma();
matrixstr += " ";
} else {
b1 = true;
}
matrixstr += "[";
bool b2 = false;
for(int index_c = 0; index_c < c; index_c++) {
if(b2) {
matrixstr += CALCULATOR->getComma();
matrixstr += " ";
} else {
b2 = true;
}
matrixstr += elementsTable->text(index_r, index_c).stripWhiteSpace();
}
matrixstr += "]";
}
matrixstr += "]";
}
accept();
}
void QalculateInsertMatrixVectorDialog::insertSelection() {
QTableSelection sel = elementsTable->selection(elementsTable->currentSelection());
if(vectorButton->isChecked()) {
bool b = false;
matrixstr = "[";
for(int index_r = sel.topRow(); index_r <= sel.bottomRow(); index_r++) {
for(int index_c = sel.leftCol(); index_c <= sel.rightCol(); index_c++) {
if(!elementsTable->text(index_r, index_c).isEmpty()) {
QString str2 = elementsTable->text(index_r, index_c).stripWhiteSpace();
if(!str2.isEmpty()) {
if(b) {
matrixstr += CALCULATOR->getComma();
matrixstr += " ";
} else {
b = true;
}
matrixstr += str2;
}
}
}
}
matrixstr += "]";
} else {
matrixstr = "[";
bool b1 = false;
for(int index_r = sel.topRow(); index_r <= sel.bottomRow(); index_r++) {
if(b1) {
matrixstr += CALCULATOR->getComma();
matrixstr += " ";
} else {
b1 = true;
}
matrixstr += "[";
bool b2 = false;
for(int index_c = sel.leftCol(); index_c <= sel.rightCol(); index_c++) {
if(b2) {
matrixstr += CALCULATOR->getComma();
matrixstr += " ";
} else {
b2 = true;
}
matrixstr += elementsTable->text(index_r, index_c).stripWhiteSpace();
}
matrixstr += "]";
}
matrixstr += "]";
}
accept();
}
QString QalculateInsertMatrixVectorDialog::editMatrixVector(const MathStructure *initial_value, bool create_vector, bool is_text_struct, bool is_result) {
if(initial_value && !initial_value->isVector()) {
return NULL;
}
if(initial_value) {
create_vector = !initial_value->isMatrix();
}
if(create_vector) {
vectorButton->setChecked(true);
elementsLabel->setText(i18n("Elements (in horizontal order):"));
} else {
matrixButton->setChecked(true);
elementsLabel->setText(i18n("Elements:"));
}
if(is_result) {
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
setButtonOKText(i18n("Insert"));
setButtonCancelText(KStdGuiItem::close().text());
#else
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 3
setButtonOK(KGuiItem(i18n("Insert")));
#else
setButtonOK(KStdGuiItem::insert());
#endif
setButtonCancel(KStdGuiItem::close());
#endif
actionButton(Cancel)->setDefault(true);
actionButton(Cancel)->setFocus();
if(create_vector) {
setCaption(i18n("Vector Result"));
} else {
setCaption(i18n("Matrix Result"));
}
} else {
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
setButtonOKText(KStdGuiItem::ok().text());
setButtonCancelText(KStdGuiItem::cancel().text());
#else
setButtonOK(KStdGuiItem::ok());
setButtonCancel(KStdGuiItem::cancel());
#endif
actionButton(Ok)->setDefault(true);
elementsTable->setFocus();
if(create_vector) {
setCaption(i18n("Vector"));
} else {
setCaption(i18n("Matrix"));
}
}
int r = 4, c = 4;
if(create_vector) {
if(initial_value) {
r = initial_value->countChildren();
c = (int) ::sqrt(r) + 4;
if(r % c > 0) {
r = r / c + 1;
} else {
r = r / c;
}
} else {
c = 4;
r = 4;
}
} else if(initial_value) {
c = initial_value->columns();
r = initial_value->rows();
}
rowsBox->setValue(r);
columnsBox->setValue(c);
elementsTable->setNumRows(r);
elementsTable->setNumCols(c);
int timeout;
if(initial_value) timeout = 3000 / (r * c);
else timeout = 3000;
printops.can_display_unicode_string_arg = (void*) elementsTable;
for(int index_r = 0; index_r < r; index_r++) {
for(int index_c = 0; index_c < c; index_c++) {
if(create_vector) {
if(initial_value && index_r * c + index_c < (int) initial_value->countChildren()) {
if(is_text_struct) elementsTable->setText(index_r, index_c, initial_value->getChild(index_r * c + index_c + 1)->symbol().c_str());
else elementsTable->setText(index_r, index_c, initial_value->getChild(index_r * c + index_c + 1)->print(printops).c_str());
} else {
elementsTable->setText(index_r, index_c, "");
}
} else {
if(initial_value) {
if(is_text_struct) elementsTable->setText(index_r, index_c, initial_value->getElement(index_r + 1, index_c + 1)->symbol().c_str());
else elementsTable->setText(index_r, index_c, initial_value->getElement(index_r + 1, index_c + 1)->print(printops).c_str());
} else {
elementsTable->setText(index_r, index_c, "0");
}
}
}
}
printops.can_display_unicode_string_arg = NULL;
matrixstr = "";
onSelectionChanged();
exec();
return matrixstr;
}
#if QT_VERSION >= 0x030200
QalculateInsertMatrixTableItem::QalculateInsertMatrixTableItem(QTable *table) : QTableItem(table, QTableItem::OnTyping) {}
#else
QalculateInsertMatrixTableItem::QalculateInsertMatrixTableItem(QTable *table) : QTableItem(table, QTableItem::OnTyping, QString::null) {}
#endif
QalculateInsertMatrixTableItem::QalculateInsertMatrixTableItem(QTable *table, const QString & text) : QTableItem(table, QTableItem::OnTyping, text) {}
int QalculateInsertMatrixTableItem::alignment() const {return Qt::AlignRight;}
#include "qalculateinsertmatrixvectordialog.moc"

@ -0,0 +1,73 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEINSERTMATRIXVECTORDIALOG_H
#define QALCULATEINSERTMATRIXVECTORDIALOG_H
#include <kdialogbase.h>
class QTable;
class QLabel;
class QSpinBox;
class QRadioButton;
class KComboBox;
class KLineEdit;
class QPushButton;
class MathStructure;
class QalculateEditNamesDialog;
class KnownVariable;
/**
@author Niklas Knutsson
*/
class QalculateInsertMatrixVectorDialog : public KDialogBase {
Q_OBJECT
public:
QalculateInsertMatrixVectorDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateInsertMatrixVectorDialog();
QString newMatrix();
QString newVector();
QString editMatrixVector(const MathStructure *initial_value = NULL, bool create_vector = false, bool is_text_struct = false, bool is_result = false);
QLabel *elementsLabel;
QRadioButton *matrixButton, *vectorButton;
QTable *elementsTable;
QSpinBox *rowsBox, *columnsBox;
QString matrixstr;
QPushButton *insertSelectionButton;
public slots:
void typeChanged(int);
void rowsChanged(int);
void columnsChanged(int);
void onSelectionChanged();
protected slots:
void slotOk();
void insertSelection();
};
#endif

@ -0,0 +1,276 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateperiodictabledialog.h"
#include "qalculate_kde_utils.h"
#include <klocale.h>
#include <qlayout.h>
#include <qlabel.h>
#include <qtooltip.h>
#include <qcolor.h>
#include <qpushbutton.h>
#include <qvbox.h>
#include <qgrid.h>
#include "qalculatebuttonwithdata.h"
#include <kiconloader.h>
#include <qfontmetrics.h>
#include <kactivelabel.h>
#include <qlineedit.h>
extern PrintOptions printops;
extern QWidget *expressionWidget;
QalculatePeriodicTableDialog::QalculatePeriodicTableDialog(QWidget *parent, const char *name)
: KDialogBase(parent, name, false, i18n("Periodic Table"), Close, Close, true) {
actionButton(Close)->setAutoDefault(false);
actionButton(Close)->setDefault(false);
grid = new QGridLayout(makeMainWidget(), 11, 20, 0, 1);
grid->addWidget(new QLabel("1", mainWidget()), 0, 1, Qt::AlignHCenter);
grid->addWidget(new QLabel("2", mainWidget()), 0, 2, Qt::AlignHCenter);
grid->addWidget(new QLabel("3", mainWidget()), 0, 4, Qt::AlignHCenter);
grid->addWidget(new QLabel("4", mainWidget()), 0, 5, Qt::AlignHCenter);
grid->addWidget(new QLabel("5", mainWidget()), 0, 6, Qt::AlignHCenter);
grid->addWidget(new QLabel("6", mainWidget()), 0, 7, Qt::AlignHCenter);
grid->addWidget(new QLabel("7", mainWidget()), 0, 8, Qt::AlignHCenter);
grid->addWidget(new QLabel("8", mainWidget()), 0, 9, Qt::AlignHCenter);
grid->addWidget(new QLabel("9", mainWidget()), 0, 10, Qt::AlignHCenter);
grid->addWidget(new QLabel("10", mainWidget()), 0, 11, Qt::AlignHCenter);
grid->addWidget(new QLabel("11", mainWidget()), 0, 12, Qt::AlignHCenter);
grid->addWidget(new QLabel("12", mainWidget()), 0, 13, Qt::AlignHCenter);
grid->addWidget(new QLabel("13", mainWidget()), 0, 14, Qt::AlignHCenter);
grid->addWidget(new QLabel("14", mainWidget()), 0, 15, Qt::AlignHCenter);
grid->addWidget(new QLabel("15", mainWidget()), 0, 16, Qt::AlignHCenter);
grid->addWidget(new QLabel("16", mainWidget()), 0, 17, Qt::AlignHCenter);
grid->addWidget(new QLabel("17", mainWidget()), 0, 18, Qt::AlignHCenter);
grid->addWidget(new QLabel("18", mainWidget()), 0, 19, Qt::AlignHCenter);
grid->addWidget(new QLabel("1 ", mainWidget()), 1, 0, Qt::AlignRight);
grid->addWidget(new QLabel("2 ", mainWidget()), 2, 0, Qt::AlignRight);
grid->addWidget(new QLabel("3 ", mainWidget()), 3, 0, Qt::AlignRight);
grid->addWidget(new QLabel("4 ", mainWidget()), 4, 0, Qt::AlignRight);
grid->addWidget(new QLabel("5 ", mainWidget()), 5, 0, Qt::AlignRight);
grid->addWidget(new QLabel("6 ", mainWidget()), 6, 0, Qt::AlignRight);
grid->addWidget(new QLabel("7 ", mainWidget()), 7, 0, Qt::AlignRight);
grid->addWidget(new QLabel("*", mainWidget()), 6, 3, Qt::AlignRight);
grid->addWidget(new QLabel("**", mainWidget()), 7, 3, Qt::AlignRight);
grid->addWidget(new QLabel("*", mainWidget()), 9, 3, Qt::AlignRight);
grid->addWidget(new QLabel("**", mainWidget()), 10, 3, Qt::AlignRight);
grid->addWidget(new QLabel(" ", mainWidget()), 8, 0);
DataSet *dc = CALCULATOR->getDataSet("atom");
if(!dc) {
return;
}
DataObject *e;
QalculateButtonWithData *e_button;
QString tip;
DataProperty *p_xpos = dc->getProperty("x_pos");
DataProperty *p_ypos = dc->getProperty("y_pos");
DataProperty *p_weight = dc->getProperty("weight");
DataProperty *p_number = dc->getProperty("number");
DataProperty *p_symbol = dc->getProperty("symbol");
DataProperty *p_class = dc->getProperty("class");
DataProperty *p_name = dc->getProperty("name");
int x_pos = 0, y_pos = 0, group = 0;
QString weight;
int w = -1;
for(size_t i = 1; i < 120; i++) {
e = dc->getObject(i2s(i));
if(e) {
x_pos = s2i(e->getProperty(p_xpos));
y_pos = s2i(e->getProperty(p_ypos));
}
if(e && x_pos > 0 && x_pos <= 18 && y_pos > 0 && y_pos <= 10) {
e_button = new QalculateButtonWithData((void*) e, e->getProperty(p_symbol).c_str(), mainWidget());
e_button->setFlat(true);
group = s2i(e->getProperty(p_class));
switch(group) {
case 1: {
e_button->setPaletteBackgroundColor(QColor(0xee, 0xcc, 0xee));
e_button->setPaletteForegroundColor(QColor(0, 0, 0));
break;
}
case 2: {
e_button->setPaletteBackgroundColor(QColor(0xdd, 0xcc, 0xee));
e_button->setPaletteForegroundColor(QColor(0, 0, 0));
break;
}
case 3: {
e_button->setPaletteBackgroundColor(QColor(0xdd, 0xdd, 0xff));
e_button->setPaletteForegroundColor(QColor(0, 0, 0));
break;
}
case 4: {
e_button->setPaletteBackgroundColor(QColor(0xdd, 0xee, 0xff));
e_button->setPaletteForegroundColor(QColor(0, 0, 0));
break;
}
case 5: {
e_button->setPaletteBackgroundColor(QColor(0xcc, 0xee, 0xee));
e_button->setPaletteForegroundColor(QColor(0, 0, 0));
break;
}
case 6: {
e_button->setPaletteBackgroundColor(QColor(0xbb, 0xff, 0xbb));
e_button->setPaletteForegroundColor(QColor(0, 0, 0));
break;
}
case 7: {
e_button->setPaletteBackgroundColor(QColor(0xee, 0xff, 0xdd));
e_button->setPaletteForegroundColor(QColor(0, 0, 0));
break;
}
case 8: {
e_button->setPaletteBackgroundColor(QColor(0xff, 0xff, 0xaa));
e_button->setPaletteForegroundColor(QColor(0, 0, 0));
break;
}
case 9: {
e_button->setPaletteBackgroundColor(QColor(0xff, 0xdd, 0xaa));
e_button->setPaletteForegroundColor(QColor(0, 0, 0));
break;
}
case 10: {
e_button->setPaletteBackgroundColor(QColor(0xff, 0xcc, 0xdd));
e_button->setPaletteForegroundColor(QColor(0, 0, 0));
break;
}
case 11: {
e_button->setPaletteBackgroundColor(QColor(0xaa, 0xee, 0xdd));
e_button->setPaletteForegroundColor(QColor(0, 0, 0));
break;
}
}
if(w < 0) {
w = e_button->fontMetrics().width("Uuo") + 12;
}
e_button->setFixedWidth(w);
e_button->setFixedHeight(w);
if(x_pos > 2) {
grid->addWidget(e_button, y_pos, x_pos + 1);
} else {
grid->addWidget(e_button, y_pos, x_pos);
}
tip = e->getProperty(p_number).c_str();
tip += " ";
tip += e->getProperty(p_name).c_str();
weight = e->getPropertyDisplayString(p_weight).c_str();
if(!weight.isEmpty() && weight != "-") {
tip += "\n";
tip += weight;
}
QToolTip::add(e_button, tip);
QObject::connect(e_button, SIGNAL(clickedWithData(void*)), this, SLOT(showElementInfo(void*)));
}
}
}
QalculatePeriodicTableDialog::~QalculatePeriodicTableDialog() {}
void QalculatePeriodicTableDialog::showElementInfo(void *e) {
DataObject *o = (DataObject*) e;
QalculateElementInfoDialog *dialog = new QalculateElementInfoDialog(o, this);
dialog->show();
}
QalculateElementInfoDialog::QalculateElementInfoDialog(DataObject *element, QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Element Data"), Close, Close, true) {
setWFlags(getWFlags() | Qt::WDestructiveClose);
e = element;
DataSet *ds = e->parentSet();
if(!ds) {
close();
return;
}
QVBox *vbox = makeVBoxMainWidget();
QVBox *vbox2 = new QVBox(vbox);
DataProperty *p_number = ds->getProperty("number");
DataProperty *p_symbol = ds->getProperty("symbol");
DataProperty *p_class = ds->getProperty("class");
DataProperty *p_name = ds->getProperty("name");
QString str = "<div align=\"right\"><font size=4>"; str += e->getProperty(p_number).c_str(); str += "</font></div>";
new KActiveLabel(str, vbox2);
str = "<font size=6>"; str += e->getProperty(p_symbol).c_str(); str += "</font>";
new KActiveLabel(str, vbox2);
str = "<font size=5>"; str += e->getProperty(p_name).c_str(); str += "</font> ";
new KActiveLabel(str, vbox2);
QalculateButtonWithData *button;
QGrid *grid = new QGrid(3, Qt::Horizontal, vbox);
int group = s2i(e->getProperty(p_class));
if(group > 0) {
str = "<b>"; str += i18n("Classification"); str += ":"; str += "</b>";
new QLabel(str, grid);
switch(group) {
case ALKALI_METALS: {str = i18n("Alkali Metal"); break;}
case ALKALI_EARTH_METALS: {str = i18n("Alkaline-Earth Metal"); break;}
case LANTHANIDES: {str = i18n("Lanthanide"); break;}
case ACTINIDES: {str = i18n("Actinide"); break;}
case TRANSITION_METALS: {str = i18n("Transition Metal"); break;}
case METALS: {str = i18n("Metal"); break;}
case METALLOIDS: {str = i18n("Metalloid"); break;}
case NONMETALS: {str = i18n("Non-Metal"); break;}
case HALOGENS: {str = i18n("Halogen"); break;}
case NOBLE_GASES: {str = i18n("Noble Gas"); break;}
case TRANSACTINIDES: {str = i18n("Transactinide"); break;}
default: {str = i18n("Unknown"); break;}
}
new KActiveLabel(str, grid);
new QFrame(grid);
}
DataPropertyIter it;
DataProperty *dp = ds->getFirstProperty(&it);
QString sval;
while(dp) {
if(!dp->isHidden() && dp != p_number && dp != p_class && dp != p_symbol && dp != p_name) {
sval = e->getPropertyDisplayString(dp).c_str();
if(!sval.isEmpty()) {
str = "<b>"; str += dp->title().c_str(); str += ":"; str += "</b>";
new QLabel(str, grid);
new KActiveLabel(sval, grid);
button = new QalculateButtonWithData((void*) dp, QIconSet(SmallIcon("editpaste")), "", grid);
QObject::connect(button, SIGNAL(clickedWithData(void*)), SLOT(insertElementData(void*)));
}
}
dp = ds->getNextProperty(&it);
}
}
QalculateElementInfoDialog::~QalculateElementInfoDialog() {}
void QalculateElementInfoDialog::insertElementData(void *data) {
DataProperty *dp = (DataProperty*) data;
DataSet *ds = dp->parentSet();
if(ds) {
QString str = ds->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionWidget).name.c_str();
str += "(";
str += e->getProperty(ds->getPrimaryKeyProperty()).c_str();
str += CALCULATOR->getComma().c_str();
str += " ";
str += dp->getName().c_str();
str += ")";
insert_text_in_expression(str);
}
}
#include "qalculateperiodictabledialog.moc"

@ -0,0 +1,66 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEPERIODICTABLEDIALOG_H
#define QALCULATEPERIODICTABLEDIALOG_H
#include <kdialogbase.h>
#include <qpushbutton.h>
class QGridLayout;
class DataObject;
/**
@author Niklas Knutsson
*/
class QalculatePeriodicTableDialog : public KDialogBase {
Q_OBJECT
public:
QalculatePeriodicTableDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculatePeriodicTableDialog();
QGridLayout *grid;
public slots:
void showElementInfo(void*);
};
class QalculateElementInfoDialog : public KDialogBase {
Q_OBJECT
public:
QalculateElementInfoDialog(DataObject *element, QWidget *parent = 0, const char *name = 0);
virtual ~QalculateElementInfoDialog();
DataObject *e;
public slots:
void insertElementData(void*);
};
#endif

@ -0,0 +1,789 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateplotdialog.h"
#include "qalculateexpressionedit.h"
#include <klineedit.h>
#include <kpushbutton.h>
#include <kcombobox.h>
#include <qlabel.h>
#include <klocale.h>
#include <qcheckbox.h>
#include <qradiobutton.h>
#include <qbuttongroup.h>
#include <qspinbox.h>
#include <kmessagebox.h>
#include <qlayout.h>
#include <ktextedit.h>
#include <klistview.h>
#include <kdeversion.h>
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
#include <qtabwidget.h>
#else
#include <ktabwidget.h>
#endif
#include <kfiledialog.h>
#include <kapplication.h>
#include <kstdguiitem.h>
extern PlotLegendPlacement default_plot_legend_placement;
extern bool default_plot_display_grid;
extern bool default_plot_full_border;
extern QString default_plot_min;
extern QString default_plot_max;
extern QString default_plot_step;
extern int default_plot_sampling_rate;
extern bool default_plot_use_sampling_rate;
extern bool default_plot_rows;
extern int default_plot_type;
extern PlotStyle default_plot_style;
extern PlotSmoothing default_plot_smoothing;
extern QString default_plot_variable;
extern bool default_plot_color;
extern bool enable_plot_expression_completion;
extern EvaluationOptions evalops;
QalculatePlotDialog::QalculatePlotDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Plot"), User1 | Close | Help, Close, false, KStdGuiItem::save()) {
actionButton(Close)->setAutoDefault(false);
actionButton(Close)->setDefault(false);
actionButton(User1)->setAutoDefault(false);
actionButton(User1)->setDefault(false);
actionButton(User1)->setEnabled(false);
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
tabs = new QTabWidget(this);
#else
tabs = new KTabWidget(this);
#endif
setMainWidget(tabs);
QWidget *page1 = new QWidget(this);
QWidget *page2 = new QWidget(this);
QWidget *page3 = new QWidget(this);
tabs->addTab(page1, i18n("Data"));
tabs->addTab(page2, i18n("Function Range"));
tabs->addTab(page3, i18n("Appearance"));
QGridLayout *grid = new QGridLayout(page1, 1, 1, spacingHint());
grid->addWidget(new QLabel(i18n("Title:"), page1), 0, 0);
seriesTitleEdit = new KLineEdit(page1);
grid->addWidget(seriesTitleEdit, 0, 1);
grid->addWidget(new QLabel(i18n("Expression:"), page1), 1, 0);
expressionEdit = new QalculateExpressionEdit(false, page1);
if(!enable_plot_expression_completion) expressionEdit->disableCompletion();
expressionEdit->updateCompletion();
grid->addWidget(expressionEdit, 1, 1);
QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 2, 2, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
typeGroup = new QButtonGroup();
functionButton = new QRadioButton(i18n("Function"), page1);
typeGroup->insert(functionButton, 0);
hbox->addWidget(functionButton);
vectorMatrixButton = new QRadioButton(i18n("Vector/matrix"), page1);
typeGroup->insert(vectorMatrixButton, 1);
hbox->addWidget(vectorMatrixButton);
pairedMatrixButton = new QRadioButton(i18n("Paired matrix"), page1);
typeGroup->insert(pairedMatrixButton, 2);
hbox->addWidget(pairedMatrixButton);
rowsButton = new QCheckBox(i18n("Rows"), page1);
hbox->addWidget(rowsButton);
xVariableLabel = new QLabel(i18n("X variable:"), page1);
grid->addWidget(xVariableLabel, 3, 0);
xVariableEdit = new KLineEdit(page1);
grid->addWidget(xVariableEdit, 3, 1);
grid->addWidget(new QLabel(i18n("Style:"), page1), 4, 0);
styleCombo = new KComboBox(page1);
styleCombo->insertItem(i18n("Line"));
styleCombo->insertItem(i18n("Points"));
styleCombo->insertItem(i18n("Line with points"));
styleCombo->insertItem(i18n("Boxes/bars"));
styleCombo->insertItem(i18n("Histogram"));
styleCombo->insertItem(i18n("Steps"));
styleCombo->insertItem(i18n("Candlesticks"));
styleCombo->insertItem(i18n("Dots"));
grid->addWidget(styleCombo, 4, 1);
grid->addWidget(new QLabel(i18n("Smoothing:"), page1), 5, 0);
smoothingCombo = new KComboBox(page1);
smoothingCombo->insertItem(i18n("None"));
smoothingCombo->insertItem(i18n("Monotonic"));
smoothingCombo->insertItem(i18n("Natural cubic splines"));
smoothingCombo->insertItem(i18n("Bezier"));
smoothingCombo->insertItem(i18n("Bezier (monotonic)"));
grid->addWidget(smoothingCombo, 5, 1);
grid->addWidget(new QLabel(i18n("Y-axis:"), page1), 6, 0);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addLayout(hbox, 6, 1);
QButtonGroup *group = new QButtonGroup();
primaryButton = new QRadioButton(i18n("Primary"), page1);
group->insert(primaryButton, 0);
hbox->addWidget(primaryButton);
secondaryButton = new QRadioButton(i18n("Secondary"), page1);
group->insert(secondaryButton, 1);
hbox->addWidget(secondaryButton);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 7, 7, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
addButton = new QPushButton(i18n("Add"), page1);
hbox->addWidget(addButton);
modifyButton = new QPushButton(i18n("Modify"), page1);
hbox->addWidget(modifyButton);
removeButton = new QPushButton(i18n("Remove"), page1);
hbox->addWidget(removeButton);
seriesView = new KListView(page1);
seriesView->addColumn(i18n("Title"));
seriesView->addColumn(i18n("Expression"));
seriesView->setRootIsDecorated(false);
seriesView->setItemsRenameable(true);
seriesView->setRenameable(0, true);
seriesView->setRenameable(1, true);
seriesView->setItemsMovable(true);
seriesView->setSorting(-1);
grid->addMultiCellWidget(seriesView, 8, 8, 0, 1);
grid = new QGridLayout(page2, 1, 1, spacingHint());
grid->addWidget(new QLabel(i18n("Min:"), page2), 0, 0);
minEdit = new KLineEdit(page2);
grid->addWidget(minEdit, 0, 1);
grid->addWidget(new QLabel(i18n("Max:"), page2), 1, 0);
maxEdit = new KLineEdit(page2);
grid->addWidget(maxEdit, 1, 1);
rangeGroup = new QButtonGroup();
samplingRateButton = new QRadioButton(i18n("Sampling rate:"), page2);
rangeGroup->insert(samplingRateButton, 0);
grid->addWidget(samplingRateButton, 2, 0);
samplingRateBox = new QSpinBox(1, 10000, 10, page2);
grid->addWidget(samplingRateBox, 2, 1);
stepSizeButton = new QRadioButton(i18n("Step size:"), page2);
rangeGroup->insert(stepSizeButton, 1);
grid->addWidget(stepSizeButton, 3, 0);
stepSizeEdit = new KLineEdit(page2);
grid->addWidget(stepSizeEdit, 3, 1);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 4, 4, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
applyRangeButton = new KPushButton(KStdGuiItem::apply(), page2);
hbox->addWidget(applyRangeButton);
grid->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 5, 0);
grid = new QGridLayout(page3, 1, 1, spacingHint());
grid->addWidget(new QLabel(i18n("Title:"), page3), 0, 0);
titleEdit = new KLineEdit(page3);
grid->addWidget(titleEdit, 0, 1);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 1, 1, 0, 1);
gridButton = new QCheckBox(i18n("Display grid"), page3);
hbox->addWidget(gridButton);
fullBorderButton = new QCheckBox(i18n("Display full border"), page3);
hbox->addWidget(fullBorderButton);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
logXButton = new QCheckBox(i18n("Logarithmic x scale:"), page3);
grid->addWidget(logXButton, 2, 0);
logXBox = new QSpinBox(2, 100, 1, page3);
grid->addWidget(logXBox, 2, 1);
logYButton = new QCheckBox(i18n("Logarithmic y scale:"), page3);
grid->addWidget(logYButton, 3, 0);
logYBox = new QSpinBox(2, 100, 1, page3);
grid->addWidget(logYBox, 3, 1);
grid->addWidget(new QLabel(i18n("X-axis label:"), page3), 4, 0);
xLabelEdit = new KLineEdit(page3);
grid->addWidget(xLabelEdit, 4, 1);
grid->addWidget(new QLabel(i18n("Y-axis label:"), page3), 5, 0);
yLabelEdit = new KLineEdit(page3);
grid->addWidget(yLabelEdit, 5, 1);
grid->addWidget(new QLabel(i18n("Color display:"), page3), 6, 0);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addLayout(hbox, 6, 1);
group = new QButtonGroup();
colorButton = new QRadioButton(i18n("Color"), page3);
group->insert(colorButton, 0);
hbox->addWidget(colorButton);
monochromeButton = new QRadioButton(i18n("Monochrome"), page3);
group->insert(monochromeButton, 1);
hbox->addWidget(monochromeButton);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
grid->addWidget(new QLabel(i18n("Legend placement:"), page3), 7, 0);
legendPlacementCombo = new KComboBox(page3);
legendPlacementCombo->insertItem(i18n("Hide"));
legendPlacementCombo->insertItem(i18n("Top-left"));
legendPlacementCombo->insertItem(i18n("Top-right"));
legendPlacementCombo->insertItem(i18n("Bottom-left"));
legendPlacementCombo->insertItem(i18n("Bottom-right"));
legendPlacementCombo->insertItem(i18n("Below"));
legendPlacementCombo->insertItem(i18n("Outside"));
grid->addWidget(legendPlacementCombo, 7, 1);
hbox = new QHBoxLayout(0, 0, spacingHint());
grid->addMultiCellLayout(hbox, 8, 8, 0, 1);
hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum));
applyAppearanceButton = new KPushButton(KStdGuiItem::apply(), page3);
hbox->addWidget(applyAppearanceButton);
grid->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding), 9, 0);
primaryButton->setChecked(true);
modifyButton->setEnabled(false);
removeButton->setEnabled(false);
gridButton->setChecked(default_plot_display_grid);
fullBorderButton->setChecked(default_plot_full_border);
rowsButton->setChecked(default_plot_rows);
colorButton->setChecked(default_plot_color);
monochromeButton->setChecked(!default_plot_color);
minEdit->setText(default_plot_min);
maxEdit->setText(default_plot_max);
stepSizeEdit->setText(default_plot_step);
xVariableEdit->setText(default_plot_variable);
samplingRateButton->setChecked(default_plot_use_sampling_rate);
samplingRateBox->setEnabled(default_plot_use_sampling_rate);
stepSizeButton->setChecked(!default_plot_use_sampling_rate);
stepSizeEdit->setEnabled(!default_plot_use_sampling_rate);
logXBox->setEnabled(false);
logYBox->setEnabled(false);
switch(default_plot_type) {
case 1: {vectorMatrixButton->setChecked(true); break;}
case 2: {pairedMatrixButton->setChecked(true); break;}
default: {functionButton->setChecked(true);}
}
rowsButton->setEnabled(default_plot_type == 1 || default_plot_type == 2);
xVariableEdit->setEnabled(default_plot_type != 1 && default_plot_type != 2);
xVariableLabel->setEnabled(default_plot_type != 1 && default_plot_type != 2);
switch(default_plot_legend_placement) {
case PLOT_LEGEND_NONE: {legendPlacementCombo->setCurrentItem(0); break;}
case PLOT_LEGEND_TOP_LEFT: {legendPlacementCombo->setCurrentItem(1); break;}
case PLOT_LEGEND_TOP_RIGHT: {legendPlacementCombo->setCurrentItem(2); break;}
case PLOT_LEGEND_BOTTOM_LEFT: {legendPlacementCombo->setCurrentItem(3); break;}
case PLOT_LEGEND_BOTTOM_RIGHT: {legendPlacementCombo->setCurrentItem(4); break;}
case PLOT_LEGEND_BELOW: {legendPlacementCombo->setCurrentItem(5); break;}
case PLOT_LEGEND_OUTSIDE: {legendPlacementCombo->setCurrentItem(6); break;}
}
switch(default_plot_smoothing) {
case PLOT_SMOOTHING_NONE: {smoothingCombo->setCurrentItem(0); break;}
case PLOT_SMOOTHING_UNIQUE: {smoothingCombo->setCurrentItem(1); break;}
case PLOT_SMOOTHING_CSPLINES: {smoothingCombo->setCurrentItem(2); break;}
case PLOT_SMOOTHING_BEZIER: {smoothingCombo->setCurrentItem(3); break;}
case PLOT_SMOOTHING_SBEZIER: {smoothingCombo->setCurrentItem(4); break;}
}
switch(default_plot_style) {
case PLOT_STYLE_LINES: {styleCombo->setCurrentItem(0); break;}
case PLOT_STYLE_POINTS: {styleCombo->setCurrentItem(1); break;}
case PLOT_STYLE_POINTS_LINES: {styleCombo->setCurrentItem(2); break;}
case PLOT_STYLE_BOXES: {styleCombo->setCurrentItem(3); break;}
case PLOT_STYLE_HISTOGRAM: {styleCombo->setCurrentItem(4); break;}
case PLOT_STYLE_STEPS: {styleCombo->setCurrentItem(5); break;}
case PLOT_STYLE_CANDLESTICKS: {styleCombo->setCurrentItem(6); break;}
case PLOT_STYLE_DOTS: {styleCombo->setCurrentItem(7); break;}
}
samplingRateBox->setValue(default_plot_sampling_rate);
seriesTitleEdit->setFocus();
connect(seriesTitleEdit, SIGNAL(returnPressed()), expressionEdit, SLOT(setFocus()));
connect(expressionEdit, SIGNAL(returnPressed()), this, SLOT(expressionActivated()));
connect(typeGroup, SIGNAL(clicked(int)), this, SLOT(typeChanged(int)));
connect(rangeGroup, SIGNAL(clicked(int)), this, SLOT(rangeTypeChanged(int)));
connect(logXButton, SIGNAL(toggled(bool)), logXBox, SLOT(setEnabled(bool)));
connect(logYButton, SIGNAL(toggled(bool)), logYBox, SLOT(setEnabled(bool)));
connect(applyRangeButton, SIGNAL(clicked()), this, SLOT(applyRange()));
connect(applyAppearanceButton, SIGNAL(clicked()), this, SLOT(applyAppearance()));
connect(seriesView, SIGNAL(selectionChanged()), this, SLOT(seriesSelected()));
connect(seriesView, SIGNAL(itemRenamed(QListViewItem*, const QString&, int)), this, SLOT(seriesItemRenamed(QListViewItem*, const QString&, int)));
connect(addButton, SIGNAL(clicked()), this, SLOT(addSeries()));
connect(modifyButton, SIGNAL(clicked()), this, SLOT(modifySeries()));
connect(removeButton, SIGNAL(clicked()), this, SLOT(removeSeries()));
connect(this, SIGNAL(user1Clicked()), this, SLOT(savePlot()));
connect(this, SIGNAL(finished()), this, SLOT(onClosing()));
}
QalculatePlotDialog::~QalculatePlotDialog() {}
void QalculatePlotDialog::slotHelp() {
KApplication::kApplication()->invokeHelp("qalculate-plotting");
}
void QalculatePlotDialog::saveMode() {
enable_plot_expression_completion = expressionEdit->completionEnabled();
default_plot_display_grid = gridButton->isChecked();
default_plot_full_border = fullBorderButton->isChecked();
default_plot_rows = rowsButton->isChecked();
default_plot_color = colorButton->isChecked();
default_plot_min = minEdit->text().ascii();
default_plot_max = maxEdit->text().ascii();
default_plot_step = stepSizeEdit->text().ascii();
default_plot_variable = xVariableEdit->text().ascii();
default_plot_use_sampling_rate = samplingRateButton->isChecked();
if(vectorMatrixButton->isChecked()) {
default_plot_type = 1;
} else if(pairedMatrixButton->isChecked()) {
default_plot_type = 2;
} else {
default_plot_type = 0;
}
switch(legendPlacementCombo->currentItem()) {
case 0: {default_plot_legend_placement = PLOT_LEGEND_NONE; break;}
case 1: {default_plot_legend_placement = PLOT_LEGEND_TOP_LEFT; break;}
case 2: {default_plot_legend_placement = PLOT_LEGEND_TOP_RIGHT; break;}
case 3: {default_plot_legend_placement = PLOT_LEGEND_BOTTOM_LEFT; break;}
case 4: {default_plot_legend_placement = PLOT_LEGEND_BOTTOM_RIGHT; break;}
case 5: {default_plot_legend_placement = PLOT_LEGEND_BELOW; break;}
case 6: {default_plot_legend_placement = PLOT_LEGEND_OUTSIDE; break;}
}
switch(smoothingCombo->currentItem()) {
case 0: {default_plot_smoothing = PLOT_SMOOTHING_NONE; break;}
case 1: {default_plot_smoothing = PLOT_SMOOTHING_UNIQUE; break;}
case 2: {default_plot_smoothing = PLOT_SMOOTHING_CSPLINES; break;}
case 3: {default_plot_smoothing = PLOT_SMOOTHING_BEZIER; break;}
case 4: {default_plot_smoothing = PLOT_SMOOTHING_SBEZIER; break;}
}
switch(styleCombo->currentItem()) {
case 0: {default_plot_style = PLOT_STYLE_LINES; break;}
case 1: {default_plot_style = PLOT_STYLE_POINTS; break;}
case 2: {default_plot_style = PLOT_STYLE_POINTS_LINES; break;}
case 3: {default_plot_style = PLOT_STYLE_BOXES; break;}
case 4: {default_plot_style = PLOT_STYLE_HISTOGRAM; break;}
case 5: {default_plot_style = PLOT_STYLE_STEPS; break;}
case 6: {default_plot_style = PLOT_STYLE_CANDLESTICKS; break;}
case 7: {default_plot_style = PLOT_STYLE_DOTS; break;}
}
default_plot_sampling_rate = samplingRateBox->value();
}
void QalculatePlotDialog::onClosing() {
tabs->setCurrentPage(0);
modifyButton->setEnabled(false);
removeButton->setEnabled(false);
actionButton(User1)->setEnabled(false);
QListViewItemIterator it(seriesView);
while(it.current()) {
MathStructure *y_vector = itemYVector[it.current()], *x_vector = itemXVector[it.current()];
if(y_vector) delete y_vector;
if(x_vector) delete x_vector;
++it;
}
itemStyle.clear();
itemType.clear();
itemAxis.clear();
itemSmoothing.clear();
itemRows.clear();
itemXVector.clear();
itemYVector.clear();
itemXVariable.clear();
seriesView->clear();
expressionEdit->clear();
seriesTitleEdit->clear();
CALCULATOR->closeGnuplot();
}
void QalculatePlotDialog::seriesItemRenamed(QListViewItem *i, const QString &str, int col) {
if(!i) return;
if(col == 0) {
updatePlot();
} else if(col == 1) {
if(str.isEmpty()) {
KMessageBox::error(this, i18n("Empty expression."));
}
MathStructure *x_vector = itemXVector[i], *y_vector = itemYVector[i];
if(x_vector) delete x_vector;
if(y_vector) delete y_vector;
x_vector = NULL;
y_vector = NULL;
generatePlotSeries(&x_vector, &y_vector, itemType[i], str.ascii(), itemXVariable[i].ascii());
itemXVector[i] = x_vector;
itemYVector[i] = y_vector;
updatePlot();
}
seriesSelected();
}
void QalculatePlotDialog::seriesSelected() {
QListViewItem *i = seriesView->selectedItem();
if(i) {
modifyButton->setEnabled(true);
removeButton->setEnabled(true);
expressionEdit->setText(i->text(1));
seriesTitleEdit->setText(i->text(0));
xVariableEdit->setText(itemXVariable[i]);
styleCombo->setCurrentItem(itemStyle[i]);
smoothingCombo->setCurrentItem(itemSmoothing[i]);
typeGroup->setButton(itemType[i]);
secondaryButton->setChecked(itemAxis[i] == 2);
primaryButton->setChecked(itemAxis[i] != 2);
rowsButton->setChecked(itemRows[i]);
} else {
modifyButton->setEnabled(false);
removeButton->setEnabled(false);
}
}
void QalculatePlotDialog::rangeTypeChanged(int i) {
stepSizeEdit->setEnabled(i == 1);
samplingRateBox->setEnabled(i == 0);
}
void QalculatePlotDialog::typeChanged(int i) {
rowsButton->setEnabled(i == 1 || i == 2);
xVariableEdit->setEnabled(i != 1 && i != 2);
xVariableLabel->setEnabled(i != 1 && i != 2);
}
void QalculatePlotDialog::expressionActivated() {
QListViewItem *i = seriesView->selectedItem();
if(i) {
modifySeries();
} else {
addSeries();
}
}
void QalculatePlotDialog::addSeries() {
QString expression = expressionEdit->text();
if(expression.stripWhiteSpace().isEmpty()) {
expressionEdit->setFocus();
KMessageBox::error(this, i18n("Empty expression."));
return;
}
int type = 0, axis = 1;
bool rows = false;
QString title = seriesTitleEdit->text();
if(vectorMatrixButton->isChecked()) {
type = 1;
} else if(pairedMatrixButton->isChecked()) {
type = 2;
}
QString str_x = xVariableEdit->text().stripWhiteSpace();
if(str_x.isEmpty() && type == 0) {
xVariableEdit->setFocus();
KMessageBox::error(this, i18n("Empty x variable."));
return;
}
expressionEdit->addToHistory(expression);
if(secondaryButton->isChecked()) {
axis = 2;
}
if((type == 1 || type == 2) && title.isEmpty()) {
Variable *v = CALCULATOR->getActiveVariable(expression.ascii());
if(v) {
title = v->title(false).c_str();
}
}
MathStructure *x_vector, *y_vector;
generatePlotSeries(&x_vector, &y_vector, type, expression.ascii(), str_x.ascii());
rows = rowsButton->isChecked();
QListViewItem *i = new KListViewItem(seriesView, seriesView->lastChild(), title, expression);
itemStyle[i] = styleCombo->currentItem();
itemSmoothing[i] = smoothingCombo->currentItem();
itemType[i] = type;
itemAxis[i] = axis;
itemRows[i] = rows;
itemXVector[i] = x_vector;
itemYVector[i] = y_vector;
itemXVariable[i] = str_x;
seriesView->setSelected(i, true);
updatePlot();
}
void QalculatePlotDialog::modifySeries() {
QListViewItem *i = seriesView->selectedItem();
if(i) {
QString expression = expressionEdit->text();
if(expression.stripWhiteSpace().isEmpty()) {
expressionEdit->setFocus();
KMessageBox::error(this, i18n("Empty expression."));
return;
}
int type = 0, axis = 1;
QString title = seriesTitleEdit->text();
if(vectorMatrixButton->isChecked()) {
type = 1;
} else if(pairedMatrixButton->isChecked()) {
type = 2;
}
QString str_x = xVariableEdit->text().stripWhiteSpace();
if(str_x.isEmpty() && type == 0) {
xVariableEdit->setFocus();
KMessageBox::error(this, i18n("Empty x variable."));
return;
}
expressionEdit->addToHistory(expression);
if(secondaryButton->isChecked()) {
axis = 2;
}
if((type == 1 || type == 2) && title.isEmpty()) {
Variable *v = CALCULATOR->getActiveVariable(expression.ascii());
if(v) {
title = v->title(false).c_str();
}
}
MathStructure *x_vector = itemXVector[i], *y_vector = itemYVector[i];
if(x_vector) delete x_vector;
if(y_vector) delete y_vector;
x_vector = NULL;
y_vector = NULL;
generatePlotSeries(&x_vector, &y_vector, type, expression.ascii(), str_x.ascii());
i->setText(0, title);
i->setText(1, expression);
itemStyle[i] = styleCombo->currentItem();
itemSmoothing[i] = smoothingCombo->currentItem();
itemType[i] = type;
itemAxis[i] = axis;
itemRows[i] = rowsButton->isChecked();
itemXVector[i] = x_vector;
itemYVector[i] = y_vector;
itemXVariable[i] = str_x;
updatePlot();
}
}
void QalculatePlotDialog::removeSeries() {
QListViewItem *i = seriesView->selectedItem();
if(i) {
MathStructure *x_vector = itemXVector[i], *y_vector = itemYVector[i];
if(x_vector) delete x_vector;
if(y_vector) delete y_vector;
itemStyle.erase(i);
itemSmoothing.erase(i);
itemType.erase(i);
itemAxis.erase(i);
itemRows.erase(i);
itemXVector.erase(i);
itemYVector.erase(i);
itemXVariable.erase(i);
delete i;
expressionEdit->clear();
seriesTitleEdit->clear();
updatePlot();
}
}
void QalculatePlotDialog::applyRange() {
QListViewItemIterator it(seriesView);
while(it.current()) {
MathStructure *x_vector = itemXVector[it.current()], *y_vector = itemYVector[it.current()];
if(y_vector) delete y_vector;
if(x_vector) delete x_vector;
x_vector = NULL;
y_vector = NULL;
generatePlotSeries(&x_vector, &y_vector, itemType[it.current()], it.current()->text(1).ascii(), itemXVariable[it.current()].ascii());
itemXVector[it.current()] = x_vector;
itemYVector[it.current()] = y_vector;
++it;
}
updatePlot();
}
void QalculatePlotDialog::applyAppearance() {
updatePlot();
}
bool QalculatePlotDialog::generatePlot(PlotParameters &pp, vector<MathStructure> &y_vectors, vector<MathStructure> &x_vectors, vector<PlotDataParameters*> &pdps) {
QListViewItemIterator it(seriesView);
if(!it.current()) {
return false;
}
while(it.current()) {
int count = 1;
QString title = it.current()->text(0), expression = it.current()->text(1);
int style = itemStyle[it.current()];
int smoothing = itemSmoothing[it.current()];
int type = itemType[it.current()];
int axis = itemAxis[it.current()];
bool rows = itemRows[it.current()];
MathStructure *x_vector = itemXVector[it.current()];
MathStructure *y_vector = itemYVector[it.current()];
if(type == 1) {
if(y_vector->isMatrix()) {
count = 0;
if(rows) {
for(size_t i = 1; i <= y_vector->rows(); i++) {
y_vectors.push_back(m_undefined);
y_vector->rowToVector(i, y_vectors[y_vectors.size() - 1]);
x_vectors.push_back(m_undefined);
count++;
}
} else {
for(size_t i = 1; i <= y_vector->columns(); i++) {
y_vectors.push_back(m_undefined);
y_vector->columnToVector(i, y_vectors[y_vectors.size() - 1]);
x_vectors.push_back(m_undefined);
count++;
}
}
} else if(y_vector->isVector()) {
y_vectors.push_back(*y_vector);
x_vectors.push_back(m_undefined);
} else {
y_vectors.push_back(*y_vector);
y_vectors[y_vectors.size() - 1].transform(STRUCT_VECTOR);
x_vectors.push_back(m_undefined);
}
} else if(type == 2) {
if(y_vector->isMatrix()) {
count = 0;
if(rows) {
for(size_t i = 1; i <= y_vector->rows(); i += 2) {
y_vectors.push_back(m_undefined);
y_vector->rowToVector(i, y_vectors[y_vectors.size() - 1]);
x_vectors.push_back(m_undefined);
y_vector->rowToVector(i + 1, x_vectors[x_vectors.size() - 1]);
count++;
}
} else {
for(size_t i = 1; i <= y_vector->columns(); i += 2) {
y_vectors.push_back(m_undefined);
y_vector->columnToVector(i, y_vectors[y_vectors.size() - 1]);
x_vectors.push_back(m_undefined);
y_vector->columnToVector(i + 1, x_vectors[x_vectors.size() - 1]);
count++;
}
}
} else if(y_vector->isVector()) {
y_vectors.push_back(*y_vector);
x_vectors.push_back(m_undefined);
} else {
y_vectors.push_back(*y_vector);
y_vectors[y_vectors.size() - 1].transform(STRUCT_VECTOR);
x_vectors.push_back(m_undefined);
}
} else {
y_vectors.push_back(*y_vector);
x_vectors.push_back(*x_vector);
}
for(int i = 0; i < count; i++) {
PlotDataParameters *pdp = new PlotDataParameters();
pdp->title = title.ascii();
if(count > 1) {
pdp->title += " :";
pdp->title += i2s(i + 1);
}
remove_blank_ends(pdp->title);
if(pdp->title.empty()) {
pdp->title = expression.ascii();
}
switch(smoothing) {
case 0: {pdp->smoothing = PLOT_SMOOTHING_NONE; break;}
case 1: {pdp->smoothing = PLOT_SMOOTHING_UNIQUE; break;}
case 2: {pdp->smoothing = PLOT_SMOOTHING_CSPLINES; break;}
case 3: {pdp->smoothing = PLOT_SMOOTHING_BEZIER; break;}
case 4: {pdp->smoothing = PLOT_SMOOTHING_SBEZIER; break;}
}
switch(style) {
case 0: {pdp->style = PLOT_STYLE_LINES; break;}
case 1: {pdp->style = PLOT_STYLE_POINTS; break;}
case 2: {pdp->style = PLOT_STYLE_POINTS_LINES; break;}
case 3: {pdp->style = PLOT_STYLE_DOTS; break;}
case 4: {pdp->style = PLOT_STYLE_BOXES; break;}
case 5: {pdp->style = PLOT_STYLE_HISTOGRAM; break;}
case 6:{pdp->style = PLOT_STYLE_STEPS; break;}
case 7: {pdp->style = PLOT_STYLE_CANDLESTICKS; break;}
}
pdp->yaxis2 = (axis == 2);
pdps.push_back(pdp);
}
++it;
}
switch(legendPlacementCombo->currentItem()) {
case 0: {pp.legend_placement = PLOT_LEGEND_NONE; break;}
case 1: {pp.legend_placement = PLOT_LEGEND_TOP_LEFT; break;}
case 2: {pp.legend_placement = PLOT_LEGEND_TOP_RIGHT; break;}
case 3: {pp.legend_placement = PLOT_LEGEND_BOTTOM_LEFT; break;}
case 4: {pp.legend_placement = PLOT_LEGEND_BOTTOM_RIGHT; break;}
case 5: {pp.legend_placement = PLOT_LEGEND_BELOW; break;}
case 6: {pp.legend_placement = PLOT_LEGEND_OUTSIDE; break;}
}
pp.title = titleEdit->text().ascii();
pp.x_label = xLabelEdit->text().ascii();
pp.y_label = yLabelEdit->text().ascii();
pp.grid = gridButton->isChecked();
pp.x_log = logXButton->isChecked();
pp.y_log = logYButton->isChecked();
pp.x_log_base = logXBox->value();
pp.y_log_base = logYBox->value();
pp.color = colorButton->isChecked();
pp.show_all_borders = fullBorderButton->isChecked();
return true;
}
void QalculatePlotDialog::savePlot() {
QString title = titleEdit->text().ascii();
if(title.isEmpty()) {
title = "plot.png";
} else {
title += ".png";
}
QString filename;
while(true) {
filename = KFileDialog::getSaveFileName(title, "image/png image/svg application/postscript image/x-eps /text/x-tex image/x-xfig", this, i18n("Save Image"));
if(filename.isEmpty()) {
return;
} else {
if(QFile::exists(filename)) {
if(KMessageBox::warningContinueCancel(this, i18n("A file named \"%1\" already exists. Are you sure you want to overwrite it?" ).arg(filename), i18n("Overwrite File?"), i18n( "&Overwrite" )) != KMessageBox::Cancel) {
break;
}
} else {
break;
}
}
}
vector<MathStructure> y_vectors;
vector<MathStructure> x_vectors;
vector<PlotDataParameters*> pdps;
PlotParameters pp;
if(generatePlot(pp, y_vectors, x_vectors, pdps)) {
pp.filename = filename.ascii();
pp.filetype = PLOT_FILETYPE_AUTO;
CALCULATOR->plotVectors(&pp, y_vectors, x_vectors, pdps);
for(size_t i = 0; i < pdps.size(); i++) {
if(pdps[i]) delete pdps[i];
}
}
}
void QalculatePlotDialog::updatePlot() {
vector<MathStructure> y_vectors;
vector<MathStructure> x_vectors;
vector<PlotDataParameters*> pdps;
PlotParameters pp;
if(!generatePlot(pp, y_vectors, x_vectors, pdps)) {
CALCULATOR->closeGnuplot();
actionButton(User1)->setEnabled(false);
return;
}
CALCULATOR->plotVectors(&pp, y_vectors, x_vectors, pdps);
actionButton(User1)->setEnabled(true);
for(size_t i = 0; i < pdps.size(); i++) {
if(pdps[i]) delete pdps[i];
}
}
void QalculatePlotDialog::generatePlotSeries(MathStructure **x_vector, MathStructure **y_vector, int type, string str, string str_x) {
EvaluationOptions eo;
eo.approximation = APPROXIMATION_APPROXIMATE;
eo.parse_options = evalops.parse_options;
eo.parse_options.read_precision = DONT_READ_PRECISION;
if(type == 1 || type == 2) {
*y_vector = new MathStructure(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo));
*x_vector = NULL;
} else {
MathStructure min(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(minEdit->text().ascii(), evalops.parse_options), eo));
MathStructure max(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(maxEdit->text().ascii(), evalops.parse_options), eo));
*x_vector = new MathStructure();
(*x_vector)->clearVector();
if(stepSizeButton->isChecked()) {
*y_vector = new MathStructure(CALCULATOR->expressionToPlotVector(str, min, max, CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(stepSizeEdit->text().ascii(), evalops.parse_options), eo), *x_vector, str_x, evalops.parse_options));
} else {
*y_vector = new MathStructure(CALCULATOR->expressionToPlotVector(str, min, max, samplingRateBox->value(), *x_vector, str_x, evalops.parse_options));
}
}
}
#include "qalculateplotdialog.moc"

@ -0,0 +1,101 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEPLOTDIALOG_H
#define QALCULATEPLOTDIALOG_H
#include <kdialogbase.h>
#include <qmap.h>
#include <qstring.h>
class KLineEdit;
class QCheckBox;
class QRadioButton;
class QSpinBox;
class QButtonGroup;
class KComboBox;
class QPushButton;
class QTabWidget;
class KListView;
class QLabel;
class QListViewItem;
class QalculateExpressionEdit;
#include "qalculate_kde_utils.h"
/**
@author Niklas Knutsson
*/
class QalculatePlotDialog : public KDialogBase {
Q_OBJECT
public:
QalculatePlotDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculatePlotDialog();
QLabel *xVariableLabel;
KLineEdit *seriesTitleEdit, *xVariableEdit, *minEdit, *maxEdit, *stepSizeEdit, *titleEdit, *xLabelEdit, *yLabelEdit;
QalculateExpressionEdit *expressionEdit;
QCheckBox *rowsButton, *gridButton, *fullBorderButton, *logXButton, *logYButton;
QRadioButton *functionButton, *vectorMatrixButton, *pairedMatrixButton, *primaryButton, *secondaryButton, *samplingRateButton, *stepSizeButton, *colorButton, *monochromeButton;
QSpinBox *samplingRateBox, *logXBox, *logYBox;
QButtonGroup *typeGroup, *rangeGroup;
KComboBox *styleCombo, *smoothingCombo, *legendPlacementCombo;
QPushButton *addButton, *modifyButton, *removeButton, *applyRangeButton, *applyAppearanceButton;
QTabWidget *tabs;
KListView *seriesView;
bool generatePlot(PlotParameters &pp, vector<MathStructure> &y_vectors, vector<MathStructure> &x_vectors, vector<PlotDataParameters*> &pdps);
void generatePlotSeries(MathStructure **x_vector, MathStructure **y_vector, int type, string str, string str_x);
QMap<QListViewItem*, int> itemStyle;
QMap<QListViewItem*, int> itemSmoothing;
QMap<QListViewItem*, int> itemType;
QMap<QListViewItem*, int> itemAxis;
QMap<QListViewItem*, bool> itemRows;
QMap<QListViewItem*, MathStructure*> itemXVector;
QMap<QListViewItem*, MathStructure*> itemYVector;
QMap<QListViewItem*, QString> itemXVariable;
protected slots:
void slotHelp();
public slots:
void onClosing();
void seriesItemRenamed(QListViewItem*, const QString&, int);
void seriesSelected();
void rangeTypeChanged(int);
void typeChanged(int);
void savePlot();
void expressionActivated();
void addSeries();
void modifySeries();
void removeSeries();
void applyRange();
void applyAppearance();
void updatePlot();
void saveMode();
};
#endif

@ -0,0 +1,54 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateprecisiondialog.h"
#include <qlabel.h>
#include <qspinbox.h>
#include <klocale.h>
#include <qhbox.h>
#include <kguiitem.h>
#include <qlayout.h>
#include <kpushbutton.h>
#include <kdeversion.h>
QalculatePrecisionDialog::QalculatePrecisionDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Precision"), Apply | Close, Close, true) {
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
setButtonApplyText(i18n("Recalculate"));
#else
setButtonApply(KGuiItem(i18n("Recalculate")));
#endif
setMainWidget(new QWidget(this));
QHBoxLayout *box = new QHBoxLayout(mainWidget());
box->setSpacing(spacingHint());
box->addWidget(new QLabel(i18n("Precision:"), mainWidget()));
precisionBox = new QSpinBox(1, 100000, 1, mainWidget());
precisionBox->setButtonSymbols(QSpinBox::PlusMinus);
box->addWidget(precisionBox);
resize(QSize(300, minimumSizeHint().height()).expandedTo(minimumSizeHint()));
}
QalculatePrecisionDialog::~QalculatePrecisionDialog() {}
#include "qalculateprecisiondialog.moc"

@ -0,0 +1,43 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEPRECISIONDIALOG_H
#define QALCULATEPRECISIONDIALOG_H
#include <kdialogbase.h>
class QSpinBox;
/**
@author Niklas Knutsson
*/
class QalculatePrecisionDialog : public KDialogBase {
Q_OBJECT
public:
QalculatePrecisionDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculatePrecisionDialog();
QSpinBox *precisionBox;
};
#endif

@ -0,0 +1,414 @@
/***************************************************************************
* Copyright (C) 2005-2006 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculatepreferencesdialog.h"
#include "qalculate_kde_utils.h"
#include <klocale.h>
#include <qbuttongroup.h>
#include <qcheckbox.h>
#include <qlabel.h>
#include <qradiobutton.h>
#include <qtooltip.h>
#include <kdeversion.h>
#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR > 1
#include <kfontrequester.h>
#endif
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
#include <qtabwidget.h>
#else
#include <ktabwidget.h>
#endif
#include <qpushbutton.h>
#include <qfont.h>
#include <qpushbutton.h>
#include <qlayout.h>
#include <kcolorbutton.h>
#include "kqalculate.h"
extern KQalculate *mainWin;
extern PrintOptions printops;
extern EvaluationOptions evalops;
extern bool fetch_exchange_rates_at_startup, save_mode_on_exit, save_defs_on_exit;
extern bool use_custom_result_font, use_custom_expression_font, use_custom_status_font;
extern QString custom_result_font, custom_expression_font, custom_status_font;
extern QWidget *expressionWidget, *resultWidget, *statusWidget_l;
extern bool close_to_systray;
extern bool display_expression_status;
extern QColor status_error_color;
extern QColor status_warning_color;
extern int use_icon_buttons;
extern bool rpn_keypad_only;
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
#include <kfontdialog.h>
class KFontRequester : public QWidget
{
Q_OBJECT
public:
KFontRequester( QWidget *parent=0L, const char *name=0L,
bool onlyFixed=false );
QFont font() const { return m_selFont; }
virtual void setFont( const QFont &font, bool onlyFixed=false );
protected:
void displaySampleText();
protected slots:
virtual void buttonClicked();
protected:
bool m_onlyFixed;
QString m_sampleText, m_title;
QLabel *m_sampleLabel;
QPushButton *m_button;
QFont m_selFont;
};
KFontRequester::KFontRequester( QWidget *parent, const char *name,
bool onlyFixed ) : QWidget( parent, name ),
m_onlyFixed( onlyFixed )
{
QHBoxLayout *layout = new QHBoxLayout( this, 0, KDialog::spacingHint() );
m_sampleLabel = new QLabel( this, "m_sampleLabel" );
m_button = new QPushButton( i18n( "Choose..." ), this, "m_button" );
m_sampleLabel->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken );
setFocusProxy( m_button );
layout->addWidget( m_sampleLabel, 1 );
layout->addWidget( m_button );
connect( m_button, SIGNAL( clicked() ), SLOT( buttonClicked() ) );
displaySampleText();
}
void KFontRequester::setFont( const QFont &font, bool onlyFixed )
{
m_selFont = font;
m_onlyFixed = onlyFixed;
displaySampleText();
}
void KFontRequester::buttonClicked()
{
int result = KFontDialog::getFont( m_selFont, m_onlyFixed, parentWidget() );
if ( result == KDialog::Accepted )
{
displaySampleText();
}
}
void KFontRequester::displaySampleText()
{
m_sampleLabel->setFont( m_selFont );
int size = m_selFont.pointSize();
if(size == -1)
size = m_selFont.pixelSize();
if ( m_sampleText.isEmpty() )
m_sampleLabel->setText( QString( "%1 %2" ).arg( m_selFont.family() )
.arg( size ) );
else
m_sampleLabel->setText( m_sampleText );
}
#endif
QalculatePreferencesDialog::QalculatePreferencesDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Preferences"), Ok | Apply | Cancel, Ok, false) {
#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2
QTabWidget *tabs = new QTabWidget(this);
#else
QTabWidget *tabs = new KTabWidget(this);
#endif
setMainWidget(tabs);
QWidget *page1 = new QWidget(this);
QWidget *page2 = new QWidget(this);
tabs->addTab(page1, i18n("General"));
tabs->addTab(page2, i18n("Fonts"));
QVBoxLayout *vbox = new QVBoxLayout(page1, spacingHint());
systrayButton = new QCheckBox(i18n("Close to system tray"), page1);
QToolTip::add(systrayButton, i18n("If the application will reside in the system tray when the window is closed"));
vbox->addWidget(systrayButton);
statusButton = new QCheckBox(i18n("Display expression status"), page1);
QToolTip::add(statusButton, i18n("If as-you-type expression status shall be displayed below the expression entry"));
vbox->addWidget(statusButton);
iconsButton = new QCheckBox(i18n("Use icon buttons"), page1);
QToolTip::add(iconsButton, i18n("Use icons instead of text on the top-right buttons. The third state uses the style setting for icons on buttons."));
iconsButton->setTristate(true);
vbox->addWidget(iconsButton);
fetchExchangeRatesButton = new QCheckBox(i18n("Update exchange rates on start"), page1);
QToolTip::add(fetchExchangeRatesButton, i18n("If current exchange rates shall be downloaded from the internet at program start"));
vbox->addWidget(fetchExchangeRatesButton);
saveModeButton = new QCheckBox(i18n("Save mode on exit"), page1);
QToolTip::add(saveModeButton, i18n("If the mode of the calculator shall be restored"));
vbox->addWidget(saveModeButton);
saveDefsButton = new QCheckBox(i18n("Save definitions on exit"), page1);
QToolTip::add(saveDefsButton, i18n("If changes to functions, units and variables shall be saved automatically"));
vbox->addWidget(saveDefsButton);
rpnKeypadOnlyButton = new QCheckBox(i18n("Use only keypad keys for RPN"), page1);
QToolTip::add(rpnKeypadOnlyButton, i18n("Use only keypad keys for RPN operations (+-*/^) and use the rest of the keyboard for expression entry"));
vbox->addWidget(rpnKeypadOnlyButton);
dotAsSeparatorButton = new QCheckBox(i18n("Ignores dots in numbers"), page1);
QToolTip::add(dotAsSeparatorButton, i18n("Allow dots, '.', to be used as thousands separator instead of as an alternative to decimal sign"));
if(CALCULATOR->getDecimalPoint() == ".") dotAsSeparatorButton->hide();
vbox->addWidget(dotAsSeparatorButton);
unicodeButton = new QCheckBox(i18n("Enable unicode signs"), page1);
QToolTip::add(unicodeButton, i18n("Disable this if you have problems with some fancy characters"));
vbox->addWidget(unicodeButton);
lowerCaseButton = new QCheckBox(i18n("Use lower case in numbers"), page1);
QToolTip::add(lowerCaseButton, i18n("If lower case letters should be used in numbers with non-decimal base"));
vbox->addWidget(lowerCaseButton);
lowerCaseEButton = new QCheckBox(i18n("Use lower case \"e\""), page1);
QToolTip::add(lowerCaseEButton, i18n("If \"e\"; shall be used instead of \"E\" in numbers"));
vbox->addWidget(lowerCaseEButton);
alternativeBasePrefixButton = new QCheckBox(i18n("Alternative base prefixes"), page1);
QToolTip::add(alternativeBasePrefixButton, i18n("If hexadecimal numbers shall be displayed with \"0x0\" and binary numbers with \"0b00\" as prefixes"));
vbox->addWidget(alternativeBasePrefixButton);
spellOutLogicalOperatorsButton = new QCheckBox(i18n("Spell out logical operators"), page1);
QToolTip::add(spellOutLogicalOperatorsButton, i18n("If logical and/or shall be displayed as \"&&\"/\"||\" or \"and\"/\"or\""));
vbox->addWidget(spellOutLogicalOperatorsButton);
QGridLayout *grid = new QGridLayout(vbox);
multiplicationLabel = new QLabel(i18n("Multiplication sign:"), page1);
grid->addWidget(multiplicationLabel, 0, 0);
QButtonGroup *group = new QButtonGroup();
dotButton = new QRadioButton(SIGN_MULTIDOT, page1);
group->insert(dotButton, 0);
grid->addWidget(dotButton, 0, 1);
exButton = new QRadioButton(SIGN_MULTIPLICATION, page1);
group->insert(exButton, 1);
grid->addWidget(exButton, 0, 2);
asteriskButton = new QRadioButton("*", page1);
group->insert(asteriskButton, 2);
grid->addWidget(asteriskButton, 0, 3);
divisionLabel = new QLabel(i18n("Division sign:"), page1);
grid->addWidget(divisionLabel, 1, 0);
group = new QButtonGroup();
divisionSlashButton = new QRadioButton(" " SIGN_DIVISION_SLASH " ", page1);
group->insert(divisionSlashButton, 0);
grid->addWidget(divisionSlashButton, 1, 1);
divisionButton = new QRadioButton(SIGN_DIVISION, page1);
group->insert(divisionButton, 1);
grid->addWidget(divisionButton, 1, 2);
slashButton = new QRadioButton("/", page1);
group->insert(slashButton, 2);
grid->addWidget(slashButton, 1, 3);
vbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
vbox = new QVBoxLayout(page2, spacingHint());
useCustomResultFontButton = new QCheckBox(i18n("Custom result font"), page2);
vbox->addWidget(useCustomResultFontButton);
resultFontEdit = new KFontRequester(page2);
vbox->addWidget(resultFontEdit);
useCustomExpressionFontButton = new QCheckBox(i18n("Custom expression font"), page2);
vbox->addWidget(useCustomExpressionFontButton);
expressionFontEdit = new KFontRequester(page2);
vbox->addWidget(expressionFontEdit);
useCustomStatusFontButton = new QCheckBox(i18n("Custom status font"), page2);
vbox->addWidget(useCustomStatusFontButton);
statusFontEdit = new KFontRequester(page2);
vbox->addWidget(statusFontEdit);
grid = new QGridLayout(vbox);
grid->addWidget(new QLabel(i18n("Status error color:"), page2), 0, 0);
#if KDE_VERSION_MAJOR == 3 && KDE_VERSION_MINOR < 1
statusErrorColorButton = new KColorButton(page2);
#else
statusErrorColorButton = new KColorButton("red", "red", page2);
#endif
grid->addWidget(statusErrorColorButton, 0, 1);
grid->addWidget(new QLabel(i18n("Status warning color:"), page2), 1, 0);
#if KDE_VERSION_MAJOR == 3 && KDE_VERSION_MINOR < 1
statusWarningColorButton = new KColorButton(page2);
#else
statusWarningColorButton = new KColorButton("blue", "blue", page2);
#endif
grid->addWidget(statusWarningColorButton, 1, 1);
vbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
connect(useCustomResultFontButton, SIGNAL(toggled(bool)), resultFontEdit, SLOT(setEnabled(bool)));
connect(useCustomExpressionFontButton, SIGNAL(toggled(bool)), expressionFontEdit, SLOT(setEnabled(bool)));
connect(useCustomStatusFontButton, SIGNAL(toggled(bool)), statusFontEdit, SLOT(setEnabled(bool)));
connect(unicodeButton, SIGNAL(toggled(bool)), multiplicationLabel, SLOT(setEnabled(bool)));
connect(unicodeButton, SIGNAL(toggled(bool)), dotButton, SLOT(setEnabled(bool)));
connect(unicodeButton, SIGNAL(toggled(bool)), exButton, SLOT(setEnabled(bool)));
connect(unicodeButton, SIGNAL(toggled(bool)), asteriskButton, SLOT(setEnabled(bool)));
connect(unicodeButton, SIGNAL(toggled(bool)), divisionLabel, SLOT(setEnabled(bool)));
connect(unicodeButton, SIGNAL(toggled(bool)), divisionSlashButton, SLOT(setEnabled(bool)));
connect(unicodeButton, SIGNAL(toggled(bool)), divisionButton, SLOT(setEnabled(bool)));
connect(unicodeButton, SIGNAL(toggled(bool)), slashButton, SLOT(setEnabled(bool)));
}
QalculatePreferencesDialog::~QalculatePreferencesDialog() {}
void QalculatePreferencesDialog::slotApply() {
rpn_keypad_only = rpnKeypadOnlyButton->isChecked();
evalops.parse_options.dot_as_separator = dotAsSeparatorButton->isChecked();
close_to_systray = systrayButton->isChecked();
display_expression_status = statusButton->isChecked();
switch(iconsButton->state()) {
case QButton::Off: {
use_icon_buttons = 0;
break;
}
case QButton::On: {
use_icon_buttons = 1;
break;
}
case QButton::NoChange: {
use_icon_buttons = -1;
break;
}
}
fetch_exchange_rates_at_startup = fetchExchangeRatesButton->isChecked();
save_mode_on_exit = saveModeButton->isChecked();
printops.use_unicode_signs = unicodeButton->isChecked();
printops.lower_case_numbers = lowerCaseButton->isChecked();
printops.lower_case_e = lowerCaseEButton->isChecked();
if(alternativeBasePrefixButton->isChecked()) printops.base_display = BASE_DISPLAY_ALTERNATIVE;
else printops.base_display = BASE_DISPLAY_NORMAL;
printops.spell_out_logical_operators = spellOutLogicalOperatorsButton->isChecked();
save_defs_on_exit = saveDefsButton->isChecked();
use_custom_result_font = useCustomResultFontButton->isChecked();
use_custom_expression_font = useCustomExpressionFontButton->isChecked();
use_custom_status_font = useCustomStatusFontButton->isChecked();
custom_result_font = resultFontEdit->font().toString();
custom_expression_font = expressionFontEdit->font().toString();
custom_status_font = statusFontEdit->font().toString();
status_error_color = statusErrorColorButton->color();
if(!status_error_color.isValid()) status_error_color.setNamedColor("red");
status_warning_color = statusWarningColorButton->color();
if(!status_warning_color.isValid()) status_warning_color.setNamedColor("blue");
if(dotButton->isChecked()) {
printops.multiplication_sign = MULTIPLICATION_SIGN_DOT;
} else if(exButton->isChecked()) {
printops.multiplication_sign = MULTIPLICATION_SIGN_X;
} else {
printops.multiplication_sign = MULTIPLICATION_SIGN_ASTERISK;
}
if(divisionSlashButton->isChecked()) {
printops.division_sign = DIVISION_SIGN_DIVISION_SLASH;
} else if(divisionButton->isChecked()) {
printops.division_sign = DIVISION_SIGN_DIVISION;
} else {
printops.division_sign = DIVISION_SIGN_SLASH;
}
mainWin->applyPreferences();
}
bool QalculatePreferencesDialog::editPreferences() {
rpnKeypadOnlyButton->setChecked(rpn_keypad_only);
dotAsSeparatorButton->setChecked(evalops.parse_options.dot_as_separator);
systrayButton->setChecked(close_to_systray);
statusButton->setChecked(display_expression_status);
if(use_icon_buttons < 0) {
iconsButton->setNoChange();
} else {
iconsButton->setChecked(use_icon_buttons > 0);
}
fetchExchangeRatesButton->setChecked(fetch_exchange_rates_at_startup);
saveModeButton->setChecked(save_mode_on_exit);
unicodeButton->setChecked(printops.use_unicode_signs);
lowerCaseButton->setChecked(printops.lower_case_numbers);
lowerCaseEButton->setChecked(printops.lower_case_e);
alternativeBasePrefixButton->setChecked(printops.base_display == BASE_DISPLAY_ALTERNATIVE);
spellOutLogicalOperatorsButton->setChecked(printops.spell_out_logical_operators);
saveDefsButton->setChecked(save_defs_on_exit);
useCustomResultFontButton->setChecked(use_custom_result_font);
useCustomExpressionFontButton->setChecked(use_custom_expression_font);
useCustomStatusFontButton->setChecked(use_custom_status_font);
QFont font1(resultWidget->font());
font1.fromString(custom_result_font);
resultFontEdit->setFont(font1);
resultFontEdit->setEnabled(use_custom_result_font);
QFont font2(expressionWidget->font());
font2.fromString(custom_expression_font);
expressionFontEdit->setFont(font2);
expressionFontEdit->setEnabled(use_custom_expression_font);
QFont font3(statusWidget_l->font());
font3.fromString(custom_status_font);
statusFontEdit->setFont(font3);
statusFontEdit->setEnabled(use_custom_status_font);
statusErrorColorButton->setColor(status_error_color);
statusWarningColorButton->setColor(status_warning_color);
if(can_display_unicode_string_function(SIGN_MULTIDOT, (void*) dotButton)) dotButton->setText(SIGN_MULTIDOT);
else dotButton->setText(SIGN_SMALLCIRCLE);
switch(printops.multiplication_sign) {
case MULTIPLICATION_SIGN_DOT: {
dotButton->setChecked(true);
break;
}
case MULTIPLICATION_SIGN_X: {
exButton->setChecked(true);
break;
}
default: {
asteriskButton->setChecked(true);
break;
}
}
asteriskButton->setEnabled(printops.use_unicode_signs);
exButton->setEnabled(printops.use_unicode_signs);
dotButton->setEnabled(printops.use_unicode_signs);
multiplicationLabel->setEnabled(printops.use_unicode_signs);
switch(printops.division_sign) {
case DIVISION_SIGN_DIVISION_SLASH: {
divisionSlashButton->setChecked(true);
break;
}
case DIVISION_SIGN_DIVISION: {
divisionButton->setChecked(true);
break;
}
default: {
slashButton->setChecked(true);
break;
}
}
slashButton->setEnabled(printops.use_unicode_signs);
divisionSlashButton->setEnabled(printops.use_unicode_signs);
divisionButton->setEnabled(printops.use_unicode_signs);
divisionLabel->setEnabled(printops.use_unicode_signs);
if(exec() == Accepted) {
slotApply();
return true;
}
return false;
}
#include "qalculatepreferencesdialog.moc"

@ -0,0 +1,57 @@
/***************************************************************************
* Copyright (C) 2005-2006 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEPREFERENCESDIALOG_H
#define QALCULATEPREFERENCESDIALOG_H
#include <kdialogbase.h>
class QCheckBox;
class QRadioButton;
class QLabel;
class KFontRequester;
class KColorButton;
/**
@author Niklas Knutsson
*/
class QalculatePreferencesDialog : public KDialogBase {
Q_OBJECT
public:
QalculatePreferencesDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculatePreferencesDialog();
bool editPreferences();
QCheckBox *rpnKeypadOnlyButton, *systrayButton, *statusButton, *iconsButton, *fetchExchangeRatesButton, *saveModeButton, *saveDefsButton, *dotAsSeparatorButton, *unicodeButton, *lowerCaseButton, *lowerCaseEButton, *alternativeBasePrefixButton, *spellOutLogicalOperatorsButton, *useCustomResultFontButton, *useCustomExpressionFontButton, *useCustomStatusFontButton;
QRadioButton *dotButton, *exButton, *asteriskButton, *divisionSlashButton, *divisionButton, *slashButton;
QLabel *multiplicationLabel, *divisionLabel;
KFontRequester *resultFontEdit, *expressionFontEdit, *statusFontEdit;
KColorButton *statusErrorColorButton, *statusWarningColorButton;
protected slots:
void slotApply();
};
#endif

@ -0,0 +1,495 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateresultdisplay.h"
#include "qalculate_kde_utils.h"
#include "kqalculate.h"
#include <kpopupmenu.h>
#include <kxmlguifactory.h>
#include <kxmlguiclient.h>
#include <kaction.h>
#include <kmessagebox.h>
#include <qwhatsthis.h>
#include <qtooltip.h>
#include <klocale.h>
#include <kapplication.h>
#include <qsimplerichtext.h>
extern vector<mode_struct> modes;
extern QString parsed_text;
extern KQalculate *mainWin;
extern MathStructure *mstruct;
extern PrintOptions printops;
extern EvaluationOptions evalops;
QString linkInfo(const MathStructure *m, QWidget *w, bool full_length = false) {
QString str;
if(m) {
if(m->isSymbolic()) {
str = "\"";
str += m->symbol().c_str();
str += "\"";
} else if(m->isVector()) {
if(m->isMatrix()) {
str = i18n("a matrix");
} else {
str = i18n("a vector");
}
str += "\n";
str += i18n("double-click to view/edit");
} else if(m->isVariable()) {
if(m->variable()->subtype() == SUBTYPE_UNKNOWN_VARIABLE) {
str = i18n("Unknown variable");
} else {
str = i18n("Variable");
}
str += ": ";
str += m->variable()->title(true).c_str();
} else if(m->isUnit()) {
str = i18n("Unit");
str += ": ";
str += m->unit()->title(true).c_str();
if(m->prefix() && m->prefix() != CALCULATOR->decimal_null_prefix && m->prefix() != CALCULATOR->binary_null_prefix) {
str += "\n";
str += i18n("Prefix");
str += ": ";
QString pstr;
switch(m->prefix()->type()) {
case PREFIX_DECIMAL: {
QTextOStream(&pstr) << m->prefix()->name(false, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) w).c_str() << " (10e" << ((DecimalPrefix*) m->prefix())->exponent() << ")";
break;
}
case PREFIX_BINARY: {
QTextOStream(&pstr) << m->prefix()->name(false, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) w).c_str() << " (2e" << ((BinaryPrefix*) m->prefix())->exponent() << ")";
break;
}
case PREFIX_NUMBER: {
QTextOStream(&pstr) << m->prefix()->name(false, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) w).c_str();
break;
}
}
str += pstr;
}
} else if(m->isFunction()) {
str = i18n("Function");
str += ": ";
str += m->function()->title(true).c_str();
Argument default_arg;
MathFunction *f = m->function();
str += "<br>";
const ExpressionName *ename = &f->preferredName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) w);
str += "<i><b>";
str += ename->name.c_str();
str += "</b>";
int iargs = f->maxargs();
if(iargs < 0) {
iargs = f->minargs() + 1;
}
str += "(";
if(iargs != 0) {
for(int i2 = 1; i2 <= iargs; i2++) {
if(i2 > f->minargs()) {
str += "[";
}
if(i2 > 1) {
str += CALCULATOR->getComma().c_str();
str += " ";
}
Argument *arg = f->getArgumentDefinition(i2);
if(arg && !arg->name().empty()) {
str += arg->name().c_str();
} else {
str += i18n("argument");
str += " ";
str += QString::number(i2);
}
if(i2 > f->minargs()) {
str += "]";
}
}
if(f->maxargs() < 0) {
str += CALCULATOR->getComma().c_str();
str += " ...";
}
}
str += ")";
str += "</i>";
if(full_length) {
str += "<i>";
for(size_t i2 = 1; i2 <= f->countNames(); i2++) {
if(&f->getName(i2) != ename) {
str += "<br>";
str += f->getName(i2).name.c_str();
}
}
str += "</i>";
if(f->subtype() == SUBTYPE_DATA_SET) {
str += "<br>";
str += "<br>";
QString str2;
str2.sprintf(i18n("Retrieves data from the %s data set for a given object and property. If \"info\" is typed as property, a dialog window will pop up with all properties of the object."), f->title().c_str());
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
}
if(!f->description().empty()) {
str += "<br>";
str += "<br>";
QString str2 = f->description().c_str();
str2.replace("<", "&lt;");
str2.replace(">", "&gt;");
str += str2;
}
}
}
}
return str;
}
QString linkInfo(const QString &link, QWidget *w, bool full_length = false) {
if(!link.isEmpty() && link[0] == '+') {
QString str = link;
str.remove(0, 1);
return str;
} else {
return linkInfo(mainWin->getResultPart(link.toInt()), w, full_length);
}
}
class QalculateExpressionToolTip : public QToolTip {
public:
QalculateResultDisplay *qrd;
QalculateExpressionToolTip(QalculateResultDisplay *parent, QToolTipGroup *group = 0) : QToolTip(parent->viewport(), group) {
qrd = parent;
}
virtual ~QalculateExpressionToolTip() {}
protected:
void maybeTip(const QPoint &p) {
int cx = qrd->contentsX();
int cy = qrd->contentsY();
QString str = qrd->anchorAt(qrd->viewportToContents(p), Qt::AnchorName);
if(str.isEmpty()) return;
int w = 5;
while(p.x() + w < qrd->visibleWidth() && qrd->anchorAt(QPoint(p.x() + cx + w, p.y() + cy), Qt::AnchorName) == str) {
w += 5;
}
int x = p.x() - 5;
w += 5;
while(x > 0 && qrd->anchorAt(QPoint(x + cx, p.y() + cy), Qt::AnchorName) == str) {
x -= 5;
w += 5;
}
if(x < 0) x = 0;
if(w + x > qrd->visibleWidth()) w = qrd->visibleWidth() - x;
int h = 5;
while(p.y() + h < qrd->visibleHeight() && qrd->anchorAt(QPoint(p.x() + cx, p.y() + cy + h), Qt::AnchorName) == str) {
h += 5;
}
int y = p.y() - 5;
h += 5;
while(y > 0 && qrd->anchorAt(QPoint(p.x() + cx, y + cy), Qt::AnchorName) == str) {
y -= 5;
h += 5;
}
if(y < 0) y = 0;
if(h + y > qrd->visibleHeight()) h = qrd->visibleHeight() - y;
tip(QRect(x, y, w, h), linkInfo(str, qrd, true));
}
};
QalculateResultDisplay::QalculateResultDisplay(QWidget *parent, const char *name): QTextBrowser(parent, name) {
setResizePolicy(AutoOneFit);
setVScrollBarMode(Auto);
setHScrollBarMode(Auto);
setTextFormat(Qt::RichText);
setFrameStyle(QFrame::NoFrame);
//setFocusPolicy(QWidget::TabFocus);
paletteChanged();
m_under_pointer = NULL;
QToolTipGroup *tgroup = new QToolTipGroup(viewport());
tooltip = new QalculateExpressionToolTip(this, tgroup);
//connect(this, SIGNAL(anchorClicked(const QString&, const QString&)), this, SLOT(onAnchorClicked(const QString&, const QString&)));
connect(this, SIGNAL(doubleClicked(int, int)), this, SLOT(onDoubleClicked(int, int)));
if(kapp) {
connect(kapp, SIGNAL(kdisplayPaletteChanged()), this, SLOT(paletteChanged()));
}
}
QalculateResultDisplay::~QalculateResultDisplay() {}
void QalculateResultDisplay::setRightMargin(int i_margin) {
setMargins(0, 0, i_margin, 0);
}
void QalculateResultDisplay::onAnchorClicked(const QString&, const QString&) {
/*if(name.isEmpty()) return;
QWhatsThis::display(linkInfo(name, this, true));*/
}
QPopupMenu *QalculateResultDisplay::createPopupMenu(const QPoint &pos) {
m_under_pointer = NULL;
QPopupMenu *menu = QTextBrowser::createPopupMenu(pos);
menu->insertSeparator();
mainWin->ActionStoreResult->plug(menu);
mainWin->ActionSaveAsImage->plug(menu);
menu->insertSeparator();
if(mstruct && mstruct->containsType(STRUCT_ADDITION)) {
if(evalops.structuring != STRUCTURING_FACTORIZE) {
mainWin->ActionFactorize->plug(menu);
}
if(evalops.structuring != STRUCTURING_SIMPLIFY) {
mainWin->ActionSimplify->plug(menu);
}
} else if(mstruct && mstruct->isNumber() && mstruct->number().isInteger() && !mstruct->number().isZero()) {
mainWin->ActionFactorize->plug(menu);
menu->insertSeparator();
}
if(mstruct && mstruct->containsUnknowns()) {
mainWin->ActionSetUnknowns->plug(menu);
}
if(mstruct && (mstruct->containsType(STRUCT_ADDITION) || mstruct->containsUnknowns())) {
menu->insertSeparator();
}
if(mstruct && mstruct->containsDivision()) {
mainWin->ActionNonZeroDenominators->plug(menu);
menu->insertSeparator();
}
int id = menu->insertItem(i18n("Normal"));
if(printops.min_exp == EXP_PRECISION) menu->setItemChecked(id, true);
else menu->connectItem(id, this, SLOT(displayNormal()));
id = menu->insertItem(i18n("Engineering"));
if(printops.min_exp == EXP_BASE_3) menu->setItemChecked(id, true);
else menu->connectItem(id, this, SLOT(displayEngineering()));
id = menu->insertItem(i18n("Scientific"));
if(printops.min_exp == EXP_SCIENTIFIC) menu->setItemChecked(id, true);
else menu->connectItem(id, this, SLOT(displayScientific()));
/*mainWin->ActionNumericalDisplayNormal->plug(menu);
mainWin->ActionNumericalDisplayEngineering->plug(menu);
mainWin->ActionNumericalDisplayScientific->plug(menu);*/
if(!mstruct || !mstruct->containsType(STRUCT_UNIT)) {
menu->insertSeparator();
mainWin->ActionNumberBaseBinary->plug(menu);
mainWin->ActionNumberBaseOctal->plug(menu);
mainWin->ActionNumberBaseDecimal->plug(menu);
mainWin->ActionNumberBaseHexadecimal->plug(menu);
menu->insertSeparator();
mainWin->ActionFractionalDisplayDecimal->plug(menu);
mainWin->ActionFractionalDisplayDecimalTryExact->plug(menu);
mainWin->ActionFractionalDisplayFraction->plug(menu);
mainWin->ActionFractionalDisplayCombined->plug(menu);
}
menu->insertSeparator();
mainWin->ActionAbbreviateNames->plug(menu);
if(mstruct && mstruct->containsType(STRUCT_UNIT)) {
menu->insertSeparator();
mainWin->ActionConvertToUnitExpression->plug(menu);
mainWin->ActionConvertToBaseUnits->plug(menu);
mainWin->ActionConvertToBestUnit->plug(menu);
menu->insertSeparator();
mainWin->ActionEnablePrefixes->plug(menu);
mainWin->ActionEnableUseOfAllPrefixes->plug(menu);
mainWin->ActionEnableDenominatorPrefixes->plug(menu);
}
menu->insertSeparator();
QPopupMenu *modes_menu = new QPopupMenu(menu);
QObject::connect(modes_menu, SIGNAL(activated(int)), mainWin, SLOT(loadMode(int)));
for(size_t i = 0; i < modes.size(); i++) {
modes_menu->insertItem(modes[i].name, i, i);
}
modes_menu->insertSeparator();
mainWin->ActionSaveModeAs->plug(modes_menu);
mainWin->ActionDeleteMode->plug(modes_menu);
menu->insertItem(i18n("Meta Modes"), modes_menu);
if(parsed_text.isEmpty()) return menu;
menu->insertSeparator();
menu->insertItem(i18n("Show Parsed Expression"), this, SLOT(showParsedExpression()));
QString str = anchorAt(pos, Qt::AnchorName);
if(!str.isEmpty()) {
if(str[0] == '+') {
name_under_pointer = str;
name_under_pointer.remove(0, 1);
menu->insertItem(i18n("Show Object Info"), this, SLOT(showInfo()));
} else {
m_under_pointer = mainWin->getResultPart(str.toInt());
if(m_under_pointer) {
if(m_under_pointer->isVector()) {
if(m_under_pointer->isMatrix()) {
menu->insertItem(i18n("View/Edit Matrix"), this, SLOT(editMatrix()));
} else {
menu->insertItem(i18n("View/Edit Vector"), this, SLOT(editVector()));
}
} else {
menu->insertItem(i18n("Show Object Info"), this, SLOT(showInfo()));
}
}
}
}
curpos = viewport()->mapToGlobal(pos);
return menu;
}
void QalculateResultDisplay::displayNormal() {
printops.negative_exponents = false;
printops.sort_options.minus_last = true;
mainWin->ActionNumericalDisplayNormal->activate();
mainWin->ActionNegativeExponents->setChecked(false);
mainWin->ActionSortMinusLast->setChecked(true);
}
void QalculateResultDisplay::displayEngineering() {
mainWin->ActionNumericalDisplayEngineering->activate();
}
void QalculateResultDisplay::displayScientific() {
printops.negative_exponents = true;
printops.sort_options.minus_last = false;
mainWin->ActionNumericalDisplayScientific->activate();
mainWin->ActionNegativeExponents->setChecked(true);
mainWin->ActionSortMinusLast->setChecked(false);
}
void QalculateResultDisplay::showParsedExpression() {
QString str = i18n("Parsed expression:");
str += "\n";
str += parsed_text;
QWhatsThis::display(str, curpos);
}
void QalculateResultDisplay::showInfo() {
if(m_under_pointer) {
QWhatsThis::display(linkInfo(m_under_pointer, this, true), curpos);
} else {
QWhatsThis::display(linkInfo(name_under_pointer, this, true), curpos);
}
}
void QalculateResultDisplay::editVector() {
mainWin->insertMatrixVector(m_under_pointer, true, false, true);
}
void QalculateResultDisplay::editMatrix() {
mainWin->insertMatrixVector(m_under_pointer, false, false, true);
}
void QalculateResultDisplay::paletteChanged() {
QPalette p = kapp ? kapp->palette() : palette();
p.setBrush(QColorGroup::Base, p.brush(QPalette::Normal, QColorGroup::Background));
p.setColor(QColorGroup::Text, p.color(QPalette::Normal, QColorGroup::Foreground));
setPalette(p);
}
void QalculateResultDisplay::virtual_hook(int, void*) {
}
void QalculateResultDisplay::focusInEvent(QFocusEvent* fe) {
QTextBrowser::focusInEvent(fe);
if(fe->reason() == QFocusEvent::Tab || fe->reason() == QFocusEvent::Backtab)
selectAll(true);
}
void QalculateResultDisplay::focusOutEvent(QFocusEvent* fe) {
QTextBrowser::focusOutEvent(fe);
if(fe->reason() == QFocusEvent::Tab || fe->reason() == QFocusEvent::Backtab)
selectAll(false);
}
void QalculateResultDisplay::onDoubleClicked(int, int) {
curpos = QCursor::pos();
QString str = anchorAt(viewportToContents(viewport()->mapFromGlobal(curpos)), Qt::AnchorName);
if(!str.isEmpty()) {
if(str[0] == '+') {
selectAll(false);
name_under_pointer = str;
name_under_pointer.remove(0, 1);
showInfo();
} else {
m_under_pointer = mainWin->getResultPart(str.toInt());
if(m_under_pointer) {
selectAll(false);
if(m_under_pointer->isVector()) {
if(m_under_pointer->isMatrix()) {
editMatrix();
} else {
editVector();
}
} else {
showInfo();
}
}
}
}
}
void QalculateResultDisplay::keyPressEvent(QKeyEvent *e) {
switch (e->key()) {
case Key_Down:
case Key_Up:
case Key_Left:
case Key_Right:
// jump over QTextEdit's key navigation breakage.
// we're not interested in keyboard navigation within the text
QWidget::keyPressEvent(e);
break;
default:
QTextBrowser::keyPressEvent(e);
}
}
QSize QalculateResultDisplay::minimumSizeHint() const {
QSize ms = minimumSize();
if((ms.width() > 0) && (ms.height() > 0))
return ms;
int w = 100;
if(ms.width() > 0)
w = ms.width();
QSimpleRichText rt("<font size=6>X</font>", font());
rt.setWidth(100);
QSimpleRichText rt2("<font size=2>X</font>", font());
rt2.setWidth(100);
int h2 = (int) (rt2.height() / 1.5);
h2 += h2 % 2;
int h = rt.height() * 2 + h2 + 2 * frameWidth();
if(h < ms.height())
h = ms.height();
return QSize(w, h);
}
QSize QalculateResultDisplay::sizeHint() const {
return minimumSizeHint();
}
#include "qalculateresultdisplay.moc"

@ -0,0 +1,79 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATERESULTDISPLAY_H
#define QALCULATERESULTDISPLAY_H
#include <qtextbrowser.h>
class QPopupMenu;
class QToolTip;
class MathStructure;
/**
@author Niklas Knutsson
*/
class QalculateResultDisplay : public QTextBrowser {
Q_OBJECT
public:
QalculateResultDisplay(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateResultDisplay();
QPopupMenu *createPopupMenu(const QPoint & pos);
QToolTip *tooltip;
const MathStructure *m_under_pointer;
QString name_under_pointer;
QPoint curpos;
QSize minimumSizeHint() const;
QSize sizeHint() const;
void setRightMargin(int);
public slots:
void onAnchorClicked(const QString&, const QString&);
void showParsedExpression();
private slots:
void paletteChanged();
void setSource(const QString &) {}
void showInfo();
void editVector();
void editMatrix();
void onDoubleClicked(int, int);
void displayEngineering();
void displayScientific();
void displayNormal();
protected:
void virtual_hook(int id, void* data);
void focusInEvent(QFocusEvent *fe);
void focusOutEvent(QFocusEvent *fe);
void keyPressEvent(QKeyEvent *e);
};
#endif

@ -0,0 +1,63 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculatesetbasedialog.h"
#include <qradiobutton.h>
#include <qvbuttongroup.h>
#include <qspinbox.h>
#include <klocale.h>
#include <qvbox.h>
QalculateSetBaseDialog::QalculateSetBaseDialog(QWidget *parent, const char *name)
: KDialogBase(parent, name, false, i18n("Number Bases"), Close, Close) {
QHBox *box = makeHBoxMainWidget();
radiogroup_output = new QVButtonGroup(i18n("Result Base"), box);
radiogroup_output->setRadioButtonExclusive(true);
new QRadioButton(i18n("Binary"), radiogroup_output);
new QRadioButton(i18n("Octal"), radiogroup_output);
new QRadioButton(i18n("Decimal"), radiogroup_output);
new QRadioButton(i18n("Hexadecimal"), radiogroup_output);
new QRadioButton(i18n("Other:"), radiogroup_output);
outputBaseBox = new QSpinBox(2, 36, 1, radiogroup_output);
outputBaseBox->setValue(10);
new QRadioButton(i18n("Sexagesimal"), radiogroup_output);
new QRadioButton(i18n("Time format"), radiogroup_output);
new QRadioButton(i18n("Roman numerals"), radiogroup_output);
radiogroup_input = new QVButtonGroup(i18n("Expression Base"), box);
radiogroup_input->setRadioButtonExclusive(true);
new QRadioButton(i18n("Binary"), radiogroup_input);
new QRadioButton(i18n("Octal"), radiogroup_input);
new QRadioButton(i18n("Decimal"), radiogroup_input);
new QRadioButton(i18n("Hexadecimal"), radiogroup_input);
new QRadioButton(i18n("Other:"), radiogroup_input);
inputBaseBox = new QSpinBox(2, 36, 1, radiogroup_input);
inputBaseBox->setValue(10);
new QRadioButton(i18n("Roman numerals"), radiogroup_input);
}
QalculateSetBaseDialog::~QalculateSetBaseDialog() {}
#include "qalculatesetbasedialog.moc"

@ -0,0 +1,45 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATESETBASEDIALOG_H
#define QALCULATESETBASEDIALOG_H
#include <kdialogbase.h>
class QVButtonGroup;
class QSpinBox;
/**
@author Niklas Knutsson
*/
class QalculateSetBaseDialog : public KDialogBase {
Q_OBJECT
public:
QalculateSetBaseDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateSetBaseDialog();
QVButtonGroup *radiogroup_input, *radiogroup_output;
QSpinBox *inputBaseBox, *outputBaseBox;
};
#endif

@ -0,0 +1,560 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculateunitsdialog.h"
#include "qalculate_kde_utils.h"
#include "qalculateeditunitdialog.h"
#include <kpushbutton.h>
#include <qsplitter.h>
#include <qvbox.h>
#include <qhbox.h>
#include <klistview.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <qlayout.h>
#include <kcombobox.h>
#include <qlabel.h>
#include <qgroupbox.h>
#include <klineedit.h>
#include <kiconloader.h>
#include <kapplication.h>
#include <kstdguiitem.h>
extern tree_struct unit_cats;
extern vector<void*> ia_units;
extern PrintOptions printops;
extern EvaluationOptions evalops;
QalculateUnitsDialog::QalculateUnitsDialog(QWidget *parent, const char *name) : KDialog(parent, name, false) {
unit_edit_dialog = NULL;
selected_category = "";
selected_unit = NULL;
selected_to_unit = NULL;
block_unit_convert = true;
QHBoxLayout *layout = new QHBoxLayout(this, marginHint(), spacingHint());
setCaption(i18n("Units"));
QVBoxLayout *leftLayout = new QVBoxLayout(layout, spacingHint());
QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
splitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
leftLayout->addWidget(splitter);
categoryView = new KListView(splitter);
categoryView->addColumn(i18n("Category"));
categoryView->setRootIsDecorated(false);
unitView = new KListView(splitter);
unitView->addColumn(i18n("Unit"));
unitView->addColumn(i18n("Names"));
unitView->addColumn(i18n("Base"));
unitView->setRootIsDecorated(false);
convertGroup = new QGroupBox(3, Qt::Horizontal, i18n("Conversion"), this);
convertGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
convertGroup->setInsideSpacing(spacingHint());
convertGroup->setInsideMargin(spacingHint());
convertButton = new KPushButton(QIconSet(SmallIcon("reload")), "", convertGroup);
fromEdit = new KLineEdit("1", convertGroup);
fromEdit->setAlignment(Qt::AlignRight);
fromEdit->setMinimumWidth(100);
fromLabel = new QLabel(convertGroup);
equalsLabel = new QLabel("=", convertGroup);
equalsLabel->setAlignment(Qt::AlignRight);
toEdit = new KLineEdit("1", convertGroup);
toEdit->setAlignment(Qt::AlignRight);
toEdit->setMinimumWidth(100);
toCombo = new KComboBox(convertGroup);
leftLayout->addWidget(convertGroup);
QVBoxLayout *buttonLayout = new QVBoxLayout(layout, spacingHint());
newButton = new QPushButton(i18n("New"), this);
buttonLayout->addWidget(newButton);
editButton = new QPushButton(i18n("Edit"), this);
editButton->setEnabled(false);
buttonLayout->addWidget(editButton);
deleteButton = new QPushButton(i18n("Delete"), this);
deleteButton->setEnabled(false);
buttonLayout->addWidget(deleteButton);
deactivateButton = new QPushButton(i18n("Deactivate"), this);
deactivateButton->setEnabled(false);
buttonLayout->addWidget(deactivateButton);
insertButton = new QPushButton(i18n("Insert"), this);
insertButton->setEnabled(false);
buttonLayout->addWidget(insertButton);
convertResultButton = new QPushButton(i18n("Convert Result"), this);
convertResultButton->setEnabled(false);
buttonLayout->addWidget(convertResultButton);
buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
helpButton = new KPushButton(KStdGuiItem::help(), this);
buttonLayout->addWidget(helpButton);
buttonClose = new KPushButton(KStdGuiItem::close(), this);
buttonLayout->addWidget(buttonClose);
fromEdit->setFocus();
resize(QSize(675, 425).expandedTo(size()));
connect(buttonClose, SIGNAL(clicked()), this, SLOT(close()));
connect(newButton, SIGNAL(clicked()), this, SLOT(newUnit()));
connect(editButton, SIGNAL(clicked()), this, SLOT(editUnit()));
connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteUnit()));
connect(deactivateButton, SIGNAL(clicked()), this, SLOT(deactivateUnit()));
connect(insertButton, SIGNAL(clicked()), this, SLOT(insertUnit()));
connect(convertResultButton, SIGNAL(clicked()), this, SLOT(convertResult()));
connect(unitView, SIGNAL(selectionChanged()), this, SLOT(unitSelected()));
connect(unitView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(unitDoubleClicked(QListViewItem*)));
connect(categoryView, SIGNAL(selectionChanged()), this, SLOT(categorySelected()));
connect(toCombo, SIGNAL(activated(int)), this, SLOT(toUnitSelected(int)));
connect(convertButton, SIGNAL(clicked()), this, SLOT(convertClicked()));
connect(fromEdit, SIGNAL(returnPressed()), this, SLOT(convert()));
connect(toEdit, SIGNAL(returnPressed()), this, SLOT(convertReversed()));
connect(fromEdit, SIGNAL(lostFocus()), this, SLOT(convert()));
connect(toEdit, SIGNAL(lostFocus()), this, SLOT(convertReversed()));
connect(helpButton, SIGNAL(clicked()), this, SLOT(slotHelp()));
}
QalculateUnitsDialog::~QalculateUnitsDialog() {
}
void QalculateUnitsDialog::slotHelp() {
KApplication::kApplication()->invokeHelp("qalculate-managers");
}
void QalculateUnitsDialog::updateUnitTree() {
unitItems.clear();
comboItems.clear();
categoryItems.clear();
categoryView->clear();
QListViewItem *i = new KListViewItem(categoryView, i18n("All")), *i2;
categoryItems[i] = i18n("All");
i->setOpen(true);
QString str;
tree_struct *item, *item2;
unit_cats.it = unit_cats.items.begin();
if(unit_cats.it != unit_cats.items.end()) {
item = &*unit_cats.it;
++unit_cats.it;
item->it = item->items.begin();
} else {
item = NULL;
}
str = "";
i2 = i;
while(item) {
str += "/";
str += item->item.c_str();
i = new KListViewItem(i2, item->item.c_str());
i->setOpen(false);
categoryItems[i] = str;
if(str == selected_category) {
categoryView->ensureItemVisible(i);
categoryView->setSelected(i, true);
}
while(item && item->it == item->items.end()) {
int str_i = str.findRev("/");
if(str_i < 0) {
str = "";
} else {
str.truncate(str_i);
}
item = item->parent;
i = i->parent();
i2 = i;
}
if(item) {
item2 = &*item->it;
if(item->it == item->items.begin())
i2 = i;
++item->it;
item = item2;
item->it = item->items.begin();
}
}
if(!unit_cats.objects.empty()) {
//add "Uncategorized" category if there are units without category
i = new KListViewItem(categoryView, i18n("Uncategorized"));
categoryItems[i] = i18n("Uncategorized");
if(selected_category == i18n("Uncategorized")) {
categoryView->ensureItemVisible(i);
categoryView->setSelected(i, true);
}
}
if(!ia_units.empty()) {
//add "Inactive" category if there are inactive units
i = new KListViewItem(categoryView, i18n("Inactive"));
categoryItems[i] = i18n("Inactive");
if(selected_category == i18n("Inactive")) {
categoryView->ensureItemVisible(i);
categoryView->setSelected(i, true);
}
}
if(!categoryView->selectedItem()) {
//if no category has been selected (previously selected has been renamed/deleted), select "All"
selected_category = i18n("All");
QListViewItemIterator it(categoryView);
if(it.current())
categoryView->setSelected(it.current(), true);
}
}
#define UPDATE_SELECTED_UNIT QListViewItem *i = unitView->selectedItem(); if(!i) return; selected_unit = unitItems[i]; if(!selected_unit) return;
#define CHECK_IF_UNIT_STILL_THERE if(!CALCULATOR->stillHasUnit(selected_unit)) {KMessageBox::error(this, i18n("Unit does not exist anymore.")); emit unitsChanged(); return;}
void QalculateUnitsDialog::insertUnit() {
UPDATE_SELECTED_UNIT
CHECK_IF_UNIT_STILL_THERE
emit insertRequest(selected_unit);
}
void QalculateUnitsDialog::convertResult() {
UPDATE_SELECTED_UNIT
CHECK_IF_UNIT_STILL_THERE
emit convertRequest(selected_unit);
}
void QalculateUnitsDialog::deactivateUnit() {
UPDATE_SELECTED_UNIT
CHECK_IF_UNIT_STILL_THERE
selected_unit->setActive(!selected_unit->isActive());
emit unitsChanged();
}
void QalculateUnitsDialog::deleteUnit() {
UPDATE_SELECTED_UNIT
CHECK_IF_UNIT_STILL_THERE
if(selected_unit->isLocal()) {
if(selected_unit->isUsedByOtherUnits()) {
//do not delete units that are used by other units
KMessageBox::error(this, i18n("Cannot delete unit as it is needed by other units."));
return;
}
//ensure that all references are removed in Calculator
selected_unit->destroy();
//update menus and trees
emit unitsChanged();
}
}
void QalculateUnitsDialog::editUnit() {
UPDATE_SELECTED_UNIT
CHECK_IF_UNIT_STILL_THERE
if(!unit_edit_dialog) {
unit_edit_dialog = new QalculateEditUnitDialog(this);
}
Unit *u = unit_edit_dialog->editUnit(QString::null, selected_unit);
if(u) {
selected_unit = u;
if(!u->isActive()) {
selected_category = i18n("Inactive");
} else if(u->category().empty()) {
selected_category = i18n("Uncategorized");
} else {
selected_category = "/";
selected_category += u->category().c_str();
}
emit unitsChanged();
}
}
void QalculateUnitsDialog::newUnit() {
if(!unit_edit_dialog) {
unit_edit_dialog = new QalculateEditUnitDialog(this);
}
Unit *u = NULL;
if(selected_category.isEmpty() || selected_category[0] != '/') {
u = unit_edit_dialog->editUnit();
} else {
QString str = selected_category;
str.remove(0, 1);
u = unit_edit_dialog->editUnit(str);
}
if(u) {
selected_unit = u;
if(!u->isActive()) {
selected_category = i18n("Inactive");
} else if(u->category().empty()) {
selected_category = i18n("Uncategorized");
} else {
selected_category = "/";
selected_category += u->category().c_str();
}
emit unitsChanged();
}
}
void QalculateUnitsDialog::unitDoubleClicked(QListViewItem*i) {
selected_unit = unitItems[i];
if(!selected_unit)
return;
CHECK_IF_UNIT_STILL_THERE
if(!unit_edit_dialog) {
unit_edit_dialog = new QalculateEditUnitDialog(this);
}
Unit *u = unit_edit_dialog->editUnit(QString::null, selected_unit);
if(u) {
selected_unit = u;
if(!u->isActive()) {
selected_category = i18n("Inactive");
} else if(u->category().empty()) {
selected_category = i18n("Uncategorized");
} else {
selected_category = "/";
selected_category += u->category().c_str();
}
emit unitsChanged();
}
}
void QalculateUnitsDialog::unitSelected() {
QListViewItem *selected = unitView->selectedItem();
if(selected) {
Unit *u = unitItems[selected];
if(!CALCULATOR->stillHasUnit(u)) {
KMessageBox::error(this, i18n("Unit does not exist anymore."));
selected_unit = NULL;
emit unitsChanged();
return;
}
//remember selection
selected_unit = u;
editButton->setEnabled(true);
insertButton->setEnabled(u->isActive());
convertResultButton->setEnabled(true);
deleteButton->setEnabled(u->isLocal());
deactivateButton->setEnabled(true);
convertGroup->setEnabled(true);
fromLabel->setText(u->print(true, printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) fromLabel).c_str());
if(u->isActive())
deactivateButton->setText(i18n("Deactivate"));
else
deactivateButton->setText(i18n("Activate"));
} else {
editButton->setEnabled(false);
insertButton->setEnabled(false);
deleteButton->setEnabled(false);
deactivateButton->setEnabled(false);
convertResultButton->setEnabled(false);
convertGroup->setEnabled(false);
selected_unit = NULL;
}
if(!block_unit_convert) convert();
}
void QalculateUnitsDialog::addUnitTreeItem(Unit *u) {
QString snames, sbase;
//display name, plural name and short name in the second column
AliasUnit *au;
for(size_t i = 1; i <= u->countNames(); i++) {
if(i > 1) snames += " / ";
snames += u->getName(i).name.c_str();
}
//depending on unit type display relation to base unit(s)
switch(u->subtype()) {
case SUBTYPE_COMPOSITE_UNIT: {
snames = "";
sbase = ((CompositeUnit*) u)->print(false, true, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) unitView).c_str();
break;
}
case SUBTYPE_ALIAS_UNIT: {
au = (AliasUnit*) u;
sbase = au->firstBaseUnit()->preferredDisplayName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) unitView).name.c_str();
if(au->firstBaseExponent() != 1) {
sbase += POWER;
sbase += QString::number(au->firstBaseExponent());
}
break;
}
case SUBTYPE_BASE_UNIT: {
sbase = "";
break;
}
}
QListViewItem *i = new KListViewItem(unitView, u->title(true).c_str(), snames, sbase);
unitItems[i] = u;
if(u == selected_unit) {
unitView->setSelected(i, true);
}
}
void QalculateUnitsDialog::categorySelected() {
block_unit_convert = true;
QListViewItem *selected = categoryView->selectedItem();
bool no_cat = false, b_all = false, b_inactive = false;
unitView->clear();
unitItems.clear();
if(!selected) {
selected_category = "";
unitSelected();
return;
}
selected_category = categoryItems[selected];
if(selected_category == i18n("All")) {
b_all = true;
} else if(selected_category == i18n("Uncategorized")) {
no_cat = true;
} else if(selected_category == i18n("Inactive")) {
b_inactive = true;
}
if(!b_all && !no_cat && !b_inactive && selected_category[0] == '/') {
string str = selected_category.ascii();
str.erase(str.begin());
for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
if(CALCULATOR->units[i]->isActive() && CALCULATOR->units[i]->category().substr(0, selected_category.length() - 1) == str) {
addUnitTreeItem(CALCULATOR->units[i]);
}
}
} else {
string str = selected_category.ascii();
for(size_t i = 0; i < CALCULATOR->units.size(); i++) {
if((b_inactive && !CALCULATOR->units[i]->isActive()) || (CALCULATOR->units[i]->isActive() && (b_all || (no_cat && CALCULATOR->units[i]->category().empty()) || (!b_inactive && CALCULATOR->units[i]->category() == str)))) {
addUnitTreeItem(CALCULATOR->units[i]);
}
}
}
if(!selected_unit || !unitView->selectedItem()) {
QListViewItemIterator it(unitView);
if(it.current())
unitView->setSelected(it.current(), true);
}
//generate convert to menu
toCombo->blockSignals(true);
toCombo->clear();
comboItems.clear();
int i = 0, h = -1;
//add all units in units tree to menu
QListViewItemIterator it(unitView);
Unit *u;
while(it.current()) {
u = unitItems[it.current()];
if(!selected_to_unit) {
selected_to_unit = u;
}
if(u) {
toCombo->insertItem(it.current()->text(0));
comboItems.push_back(u);
if(selected_to_unit == u)
h = i;
}
i++;
++it;
}
//if no items were added to the menu, reset selected unit
if(i == 0) {
selected_to_unit = NULL;
} else {
//if no menu item was selected, select the first
if(h < 0) {
h = 0;
QListViewItemIterator it2(unitView);
if(it2.current()) {
selected_to_unit = unitItems[it2.current()];
} else {
selected_to_unit = NULL;
}
}
toCombo->setCurrentItem(h);
}
toCombo->blockSignals(false);
block_unit_convert = false;
//update conversion display
convert();
}
void QalculateUnitsDialog::toUnitSelected(int index) {
if(index < (int) comboItems.size()) {
selected_to_unit = comboItems[index];
convert();
}
}
void QalculateUnitsDialog::convertClicked() {
if(toEdit->hasFocus()) {
convertReversed();
} else {
convert();
}
}
void QalculateUnitsDialog::convert() {
if(selected_unit && selected_to_unit) {
//determine conversion direction
bool b = false;
if(selected_unit == selected_to_unit) {
toEdit->setText(fromEdit->text());
} else {
EvaluationOptions eo;
eo.approximation = APPROXIMATION_APPROXIMATE;
eo.parse_options.angle_unit = evalops.parse_options.angle_unit;
PrintOptions po;
po.is_approximate = &b;
po.number_fraction_format = FRACTION_DECIMAL;
MathStructure v_mstruct = CALCULATOR->convert(CALCULATOR->unlocalizeExpression(fromEdit->text().ascii(), evalops.parse_options), selected_unit, selected_to_unit, eo);
toEdit->setText(v_mstruct.print(po).c_str());
b = b || v_mstruct.isApproximate();
}
if(b && printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) equalsLabel)) {
equalsLabel->setText(SIGN_ALMOST_EQUAL);
} else {
equalsLabel->setText("=");
}
}
}
void QalculateUnitsDialog::convertReversed() {
if(selected_unit && selected_to_unit) {
bool b = false;
if(selected_unit == selected_to_unit) {
fromEdit->setText(toEdit->text());
} else {
EvaluationOptions eo;
eo.approximation = APPROXIMATION_APPROXIMATE;
eo.parse_options.angle_unit = evalops.parse_options.angle_unit;
PrintOptions po;
po.is_approximate = &b;
po.number_fraction_format = FRACTION_DECIMAL;
MathStructure v_mstruct = CALCULATOR->convert(CALCULATOR->unlocalizeExpression(toEdit->text().ascii(), evalops.parse_options), selected_to_unit, selected_unit, eo);
fromEdit->setText(v_mstruct.print(po).c_str());
b = b || v_mstruct.isApproximate();
}
if(b && printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) equalsLabel)) {
equalsLabel->setText(SIGN_ALMOST_EQUAL);
} else {
equalsLabel->setText("=");
}
}
}
void QalculateUnitsDialog::keyPressEvent(QKeyEvent *e) {
if(e->key() == Key_Return) {
convertClicked();
e->accept();
return;
}
KDialog::keyPressEvent(e);
}
#include "qalculateunitsdialog.moc"

@ -0,0 +1,108 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEUNITSDIALOG_H
#define QALCULATEUNITSDIALOG_H
#include <kdialog.h>
#include <qmap.h>
#include <qvaluevector.h>
class Unit;
class QalculateEditUnitDialog;
class KListView;
class QListViewItem;
class QPushButton;
class KLineEdit;
class QLabel;
class KComboBox;
class QGroupBox;
/**
@author Niklas Knutsson
*/
class QalculateUnitsDialog : public KDialog {
Q_OBJECT
public:
QalculateUnitsDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateUnitsDialog();
QalculateEditUnitDialog *unit_edit_dialog;
QString selected_category;
Unit *selected_unit, *selected_to_unit;
void addUnitTreeItem(Unit *f);
QMap<QListViewItem*, Unit*> unitItems;
QMap<QListViewItem*, QString> categoryItems;
QValueVector<Unit*> comboItems;
QGroupBox *convertGroup;
KListView *categoryView;
KListView *unitView;
QPushButton *newButton;
QPushButton *editButton;
QPushButton *deleteButton;
QPushButton *deactivateButton;
QPushButton *insertButton;
QPushButton *helpButton;
QPushButton *buttonClose;
QPushButton *convertResultButton;
QPushButton *convertButton;
QLabel *fromLabel, *equalsLabel;
KLineEdit *toEdit, *fromEdit;
KComboBox *toCombo;
bool block_unit_convert;
public slots:
void updateUnitTree();
void unitDoubleClicked(QListViewItem*);
void unitSelected();
void categorySelected();
void insertUnit();
void deactivateUnit();
void deleteUnit();
void editUnit();
void newUnit();
void convertResult();
void convertClicked();
void convert();
void convertReversed();
void toUnitSelected(int);
protected slots:
void slotHelp();
signals:
void unitsChanged();
void insertRequest(Unit*);
void convertRequest(Unit*);
protected:
void keyPressEvent(QKeyEvent *e);
};
#endif

@ -0,0 +1,493 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "qalculatevariablesdialog.h"
#include "qalculate_kde_utils.h"
#include "qalculateeditvariabledialog.h"
#include "qalculateeditmatrixvectordialog.h"
#include "qalculateeditunknownvariabledialog.h"
#include "qalculateexportcsvdialog.h"
#include <kpushbutton.h>
#include <qsplitter.h>
#include <qvbox.h>
#include <qhbox.h>
#include <klistview.h>
#include <kmessagebox.h>
#include <klocale.h>
#include <qlayout.h>
#include <kapplication.h>
#include <kstdguiitem.h>
extern tree_struct variable_cats;
extern vector<void*> ia_variables;
QalculateVariablesDialog::QalculateVariablesDialog(QWidget *parent, const char *name) : KDialog(parent, name, false) {
export_csv_dialog = NULL;
variable_edit_dialog = NULL;
matrix_edit_dialog = NULL;
unknown_edit_dialog = NULL;
selected_category = "";
selected_variable = NULL;
QHBoxLayout *layout = new QHBoxLayout(this, marginHint(), spacingHint());
setCaption(i18n("Variables"));
QSplitter *splitter = new QSplitter(Qt::Horizontal, this);
layout->addWidget(splitter);
categoryView = new KListView(splitter);
categoryView->addColumn(i18n("Category"));
variableView = new KListView(splitter);
variableView->addColumn(i18n("Variable Name"));
variableView->addColumn(i18n("Value"));
variableView->setRootIsDecorated(false);
QVBoxLayout *buttonLayout = new QVBoxLayout(layout, spacingHint());
newButton = new QPushButton(i18n("New"), this);
buttonLayout->addWidget(newButton);
editButton = new QPushButton(i18n("Edit"), this);
editButton->setEnabled(false);
buttonLayout->addWidget(editButton);
deleteButton = new QPushButton(i18n("Delete"), this);
deleteButton->setEnabled(false);
buttonLayout->addWidget(deleteButton);
deactivateButton = new QPushButton(i18n("Deactivate"), this);
deactivateButton->setEnabled(false);
buttonLayout->addWidget(deactivateButton);
insertButton = new QPushButton(i18n("Insert"), this);
insertButton->setEnabled(false);
buttonLayout->addWidget(insertButton);
exportButton = new QPushButton(i18n("Export"), this);
exportButton->setEnabled(false);
buttonLayout->addWidget(exportButton);
buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding));
helpButton = new KPushButton(KStdGuiItem::help(), this);
buttonLayout->addWidget(helpButton);
buttonClose = new KPushButton(KStdGuiItem::close(), this);
buttonClose->setFocus();
buttonLayout->addWidget(buttonClose);
resize(QSize(675, 375).expandedTo(size()));
connect(buttonClose, SIGNAL(clicked()), this, SLOT(close()));
connect(newButton, SIGNAL(clicked()), this, SLOT(newVariable()));
connect(editButton, SIGNAL(clicked()), this, SLOT(editVariable()));
connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteVariable()));
connect(deactivateButton, SIGNAL(clicked()), this, SLOT(deactivateVariable()));
connect(insertButton, SIGNAL(clicked()), this, SLOT(insertVariable()));
connect(exportButton, SIGNAL(clicked()), this, SLOT(exportVariable()));
connect(variableView, SIGNAL(selectionChanged()), this, SLOT(variableSelected()));
connect(variableView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(variableDoubleClicked(QListViewItem*)));
connect(categoryView, SIGNAL(selectionChanged()), this, SLOT(categorySelected()));
connect(helpButton, SIGNAL(clicked()), this, SLOT(slotHelp()));
}
QalculateVariablesDialog::~QalculateVariablesDialog() {}
void QalculateVariablesDialog::slotHelp() {
KApplication::kApplication()->invokeHelp("qalculate-managers");
}
void QalculateVariablesDialog::updateVariableTree() {
variableItems.clear();
categoryItems.clear();
categoryView->clear();
QListViewItem *i = new KListViewItem(categoryView, i18n("All")), *i2;
categoryItems[i] = i18n("All");
i->setOpen(true);
QString str;
tree_struct *item, *item2;
variable_cats.it = variable_cats.items.begin();
if(variable_cats.it != variable_cats.items.end()) {
item = &*variable_cats.it;
++variable_cats.it;
item->it = item->items.begin();
} else {
item = NULL;
}
str = "";
i2 = i;
while(item) {
str += "/";
str += item->item.c_str();
i = new KListViewItem(i2, item->item.c_str());
i->setOpen(false);
categoryItems[i] = str;
if(str == selected_category) {
categoryView->ensureItemVisible(i);
categoryView->setSelected(i, true);
}
while(item && item->it == item->items.end()) {
int str_i = str.findRev("/");
if(str_i < 0) {
str = "";
} else {
str.truncate(str_i);
}
item = item->parent;
i = i->parent();
i2 = i;
}
if(item) {
item2 = &*item->it;
if(item->it == item->items.begin())
i2 = i;
++item->it;
item = item2;
item->it = item->items.begin();
}
}
if(!variable_cats.objects.empty()) {
//add "Uncategorized" category if there are variables without category
i = new KListViewItem(categoryView, i18n("Uncategorized"));
categoryItems[i] = i18n("Uncategorized");
if(selected_category == i18n("Uncategorized")) {
categoryView->ensureItemVisible(i);
categoryView->setSelected(i, true);
}
}
if(!ia_variables.empty()) {
//add "Inactive" category if there are inactive variables
i = new KListViewItem(categoryView, i18n("Inactive"));
categoryItems[i] = i18n("Inactive");
if(selected_category == i18n("Inactive")) {
categoryView->ensureItemVisible(i);
categoryView->setSelected(i, true);
}
}
if(!categoryView->selectedItem()) {
//if no category has been selected (previously selected has been renamed/deleted), select "All"
selected_category = i18n("All");
QListViewItemIterator it(categoryView);
if(it.current())
categoryView->setSelected(it.current(), true);
}
}
#define UPDATE_SELECTED_VARIABLE QListViewItem *i = variableView->selectedItem(); if(!i) return; selected_variable = variableItems[i]; if(!selected_variable) return;
#define CHECK_IF_VARIABLE_STILL_THERE if(!CALCULATOR->stillHasVariable(selected_variable)) {KMessageBox::error(this, i18n("Variable does not exist anymore.")); emit variablesChanged(); return;}
void QalculateVariablesDialog::exportVariable() {
UPDATE_SELECTED_VARIABLE
CHECK_IF_VARIABLE_STILL_THERE
if(selected_variable->isKnown()) {
if(!export_csv_dialog) {
export_csv_dialog = new QalculateExportCSVDialog(this);
}
export_csv_dialog->exportCSVFile((KnownVariable*) selected_variable);
}
}
void QalculateVariablesDialog::insertVariable() {
UPDATE_SELECTED_VARIABLE
CHECK_IF_VARIABLE_STILL_THERE
emit insertRequest(selected_variable);
}
void QalculateVariablesDialog::deactivateVariable() {
UPDATE_SELECTED_VARIABLE
CHECK_IF_VARIABLE_STILL_THERE
selected_variable->setActive(!selected_variable->isActive());
emit variablesChanged();
}
void QalculateVariablesDialog::deleteVariable() {
UPDATE_SELECTED_VARIABLE
CHECK_IF_VARIABLE_STILL_THERE
if(selected_variable->isLocal()) {
//ensure that all references are removed in Calculator
selected_variable->destroy();
//update menus and trees
emit variablesChanged();
}
}
void QalculateVariablesDialog::editVariable() {
UPDATE_SELECTED_VARIABLE
CHECK_IF_VARIABLE_STILL_THERE
Variable *v = NULL;
if(selected_variable->isKnown()) {
if(((KnownVariable*) selected_variable)->get().isVector()) {
if(!matrix_edit_dialog) {
matrix_edit_dialog = new QalculateEditMatrixVectorDialog(this);
}
v = matrix_edit_dialog->editVariable(QString::null, (KnownVariable*) selected_variable);
} else {
if(!variable_edit_dialog) {
variable_edit_dialog = new QalculateEditVariableDialog(this);
}
v = variable_edit_dialog->editVariable(QString::null, (KnownVariable*) selected_variable);
}
} else {
if(!unknown_edit_dialog) {
unknown_edit_dialog = new QalculateEditUnknownVariableDialog(this);
}
v = unknown_edit_dialog->editVariable(QString::null, (UnknownVariable*) selected_variable);
}
if(v) {
selected_variable = v;
if(!v->isActive()) {
selected_category = i18n("Inactive");
} else if(v->category().empty()) {
selected_category = i18n("Uncategorized");
} else {
selected_category = "/";
selected_category += v->category().c_str();
}
emit variablesChanged();
}
}
void QalculateVariablesDialog::newVariable() {
if(!variable_edit_dialog) {
variable_edit_dialog = new QalculateEditVariableDialog(this);
}
Variable *v = NULL;
if(selected_category.isEmpty() || selected_category[0] != '/') {
v = variable_edit_dialog->editVariable("");
} else {
QString str = selected_category;
str.remove(0, 1);
v = variable_edit_dialog->editVariable(str);
}
if(v) {
selected_variable = v;
if(!v->isActive()) {
selected_category = i18n("Inactive");
} else if(v->category().empty()) {
selected_category = i18n("Uncategorized");
} else {
selected_category = "/";
selected_category += v->category().c_str();
}
emit variablesChanged();
}
}
void QalculateVariablesDialog::variableDoubleClicked(QListViewItem*i) {
selected_variable = variableItems[i];
if(!selected_variable)
return;
CHECK_IF_VARIABLE_STILL_THERE
Variable *v = NULL;
if(selected_variable->isKnown()) {
if(((KnownVariable*) selected_variable)->get().isVector()) {
if(!matrix_edit_dialog) {
matrix_edit_dialog = new QalculateEditMatrixVectorDialog(this);
}
v = matrix_edit_dialog->editVariable(QString::null, (KnownVariable*) selected_variable);
} else {
if(!variable_edit_dialog) {
variable_edit_dialog = new QalculateEditVariableDialog(this);
}
v = variable_edit_dialog->editVariable(QString::null, (KnownVariable*) selected_variable);
}
} else {
if(!unknown_edit_dialog) {
unknown_edit_dialog = new QalculateEditUnknownVariableDialog(this);
}
v = unknown_edit_dialog->editVariable(QString::null, (UnknownVariable*) selected_variable);
}
if(v) {
selected_variable = v;
if(!v->isActive()) {
selected_category = i18n("Inactive");
} else if(v->category().empty()) {
selected_category = i18n("Uncategorized");
} else {
selected_category = "/";
selected_category += v->category().c_str();
}
emit variablesChanged();
}
}
void QalculateVariablesDialog::variableSelected() {
QListViewItem *selected = variableView->selectedItem();
if(selected) {
Variable *v = variableItems[selected];
if(!CALCULATOR->stillHasVariable(v)) {
KMessageBox::error(this, i18n("Variable does not exist anymore."));
selected_variable = NULL;
emit variablesChanged();
return;
}
//remember selection
selected_variable = v;
editButton->setEnabled(!is_answer_variable(v));
insertButton->setEnabled(v->isActive());
deleteButton->setEnabled(v->isLocal() && !is_answer_variable(v) && v != CALCULATOR->v_x && v != CALCULATOR->v_y && v != CALCULATOR->v_z);
deactivateButton->setEnabled(!is_answer_variable(v));
if(v->isActive())
deactivateButton->setText(i18n("Deactivate"));
else
deactivateButton->setText(i18n("Activate"));
exportButton->setEnabled(v->isKnown());
} else {
editButton->setEnabled(false);
insertButton->setEnabled(false);
deleteButton->setEnabled(false);
deactivateButton->setEnabled(false);
exportButton->setEnabled(false);
selected_variable = NULL;
}
}
void QalculateVariablesDialog::addVariableTreeItem(Variable *v) {
QString value;
if(is_answer_variable(v)) {
value = i18n("a previous result");
} else if(v->isKnown()) {
if(((KnownVariable*) v)->isExpression()) {
value = CALCULATOR->localizeExpression(((KnownVariable*) v)->expression()).c_str();
if(value.length() > 20) {
value.truncate(17);
value += "...";
}
} else {
if(((KnownVariable*) v)->get().isMatrix()) {
value = i18n("matrix");
} else if(((KnownVariable*) v)->get().isVector()) {
value = i18n("vector");
} else {
value = CALCULATOR->printMathStructureTimeOut(((KnownVariable*) v)->get(), 30).c_str();
}
}
} else {
if(((UnknownVariable*) v)->assumptions()) {
switch(((UnknownVariable*) v)->assumptions()->sign()) {
case ASSUMPTION_SIGN_POSITIVE: {
value = i18n("positive");
break;
}
case ASSUMPTION_SIGN_NONPOSITIVE: {
value = i18n("non-positive");
break;
}
case ASSUMPTION_SIGN_NEGATIVE: {
value = i18n("negative");
break;
}
case ASSUMPTION_SIGN_NONNEGATIVE: {
value = i18n("non-negative");
break;
}
case ASSUMPTION_SIGN_NONZERO: {
value = i18n("non-zero");
break;
}
default: {}
}
if(!value.isEmpty() && !((UnknownVariable*) v)->assumptions()->type() == ASSUMPTION_TYPE_NONE)
value += " ";
switch(((UnknownVariable*) v)->assumptions()->type()) {
case ASSUMPTION_TYPE_INTEGER: {
value += i18n("integer");
break;
}
case ASSUMPTION_TYPE_RATIONAL: {
value += i18n("rational");
break;
}
case ASSUMPTION_TYPE_REAL: {
value += i18n("real");
break;
}
case ASSUMPTION_TYPE_COMPLEX: {
value += i18n("complex");
break;
}
case ASSUMPTION_TYPE_NUMBER: {
value += i18n("number");
break;
}
case ASSUMPTION_TYPE_NONMATRIX: {
value += i18n("(not matrix)");
break;
}
default: {}
}
if(value.isEmpty())
value = i18n("unknown");
} else {
value = i18n("default assumptions");
}
}
QListViewItem *i = new KListViewItem(variableView, v->title(true).c_str(), value);
variableItems[i] = v;
if(v == selected_variable) {
variableView->setSelected(i, true);
}
}
void QalculateVariablesDialog::categorySelected() {
QListViewItem *selected = categoryView->selectedItem();
bool no_cat = false, b_all = false, b_inactive = false;
variableView->clear();
variableItems.clear();
if(!selected) {
selected_category = "";
variableSelected();
return;
}
selected_category = categoryItems[selected];
if(selected_category == i18n("All")) {
b_all = true;
} else if(selected_category == i18n("Uncategorized")) {
no_cat = true;
} else if(selected_category == i18n("Inactive")) {
b_inactive = true;
}
if(!b_all && !no_cat && !b_inactive && selected_category[0] == '/') {
string str = selected_category.ascii();
str.erase(str.begin());
for(size_t i = 0; i < CALCULATOR->variables.size(); i++) {
if(CALCULATOR->variables[i]->isActive() && CALCULATOR->variables[i]->category().substr(0, selected_category.length() - 1) == str) {
addVariableTreeItem(CALCULATOR->variables[i]);
}
}
} else {
string str = selected_category.ascii();
for(size_t i = 0; i < CALCULATOR->variables.size(); i++) {
if((b_inactive && !CALCULATOR->variables[i]->isActive()) || (CALCULATOR->variables[i]->isActive() && (b_all || (no_cat && CALCULATOR->variables[i]->category().empty()) || (!b_inactive && CALCULATOR->variables[i]->category() == str)))) {
addVariableTreeItem(CALCULATOR->variables[i]);
}
}
}
if(!selected_variable || !variableView->selectedItem()) {
QListViewItemIterator it(variableView);
if(it.current())
variableView->setSelected(it.current(), true);
}
}
#include "qalculatevariablesdialog.moc"

@ -0,0 +1,92 @@
/***************************************************************************
* Copyright (C) 2005 by Niklas Knutsson *
* nq@altern.org *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#ifndef QALCULATEVARIABLESDIALOG_H
#define QALCULATEVARIABLESDIALOG_H
#include <kdialog.h>
#include <qmap.h>
class Variable;
class QalculateEditVariableDialog;
class QalculateEditMatrixVectorDialog;
class QalculateEditUnknownVariableDialog;
class QalculateExportCSVDialog;
class KListView;
class QListViewItem;
class QPushButton;
/**
@author Niklas Knutsson
*/
class QalculateVariablesDialog : public KDialog {
Q_OBJECT
public:
QalculateVariablesDialog(QWidget *parent = 0, const char *name = 0);
virtual ~QalculateVariablesDialog();
QalculateEditVariableDialog *variable_edit_dialog;
QalculateEditMatrixVectorDialog *matrix_edit_dialog;
QalculateEditUnknownVariableDialog *unknown_edit_dialog;
QalculateExportCSVDialog *export_csv_dialog;
QString selected_category;
Variable *selected_variable;
void addVariableTreeItem(Variable *v);
QMap<QListViewItem*, Variable*> variableItems;
QMap<QListViewItem*, QString> categoryItems;
KListView *categoryView;
KListView *variableView;
QPushButton *newButton;
QPushButton *editButton;
QPushButton *deleteButton;
QPushButton *deactivateButton;
QPushButton *insertButton;
QPushButton *exportButton;
QPushButton *helpButton;
QPushButton *buttonClose;
public slots:
void updateVariableTree();
void variableDoubleClicked(QListViewItem*);
void variableSelected();
void categorySelected();
void exportVariable();
void insertVariable();
void deactivateVariable();
void deleteVariable();
void editVariable();
void newVariable();
protected slots:
void slotHelp();
signals:
void variablesChanged();
void insertRequest(Variable*);
};
#endif
Loading…
Cancel
Save