From ee0c9d4bc3e25a409b3127be2876079f69719978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sl=C3=A1vek=20Banko?= Date: Sat, 9 Apr 2016 15:59:57 +0200 Subject: [PATCH] Initial import of qalculate-kde 0.9.7 --- AUTHORS | 1 + COPYING | 340 + ChangeLog | 477 ++ INSTALL | 167 + Makefile.am | 22 + Makefile.cvs | 10 + NEWS | 0 README | 0 TODO | 0 configure.in.in | 20 + doc/Makefile.am | 4 + doc/en/Makefile.am | 4 + doc/en/qalculate_kde/Makefile.am | 2 + doc/en/qalculate_kde/calculation-history.png | Bin 0 -> 52992 bytes doc/en/qalculate_kde/calculator-buttons.png | Bin 0 -> 85174 bytes doc/en/qalculate_kde/completion.png | Bin 0 -> 22331 bytes doc/en/qalculate_kde/convert-number-bases.png | Bin 0 -> 15880 bytes doc/en/qalculate_kde/convert-unit.png | Bin 0 -> 12989 bytes doc/en/qalculate_kde/edit-function.png | Bin 0 -> 28439 bytes doc/en/qalculate_kde/edit-matrix.png | Bin 0 -> 28460 bytes doc/en/qalculate_kde/edit-unit.png | Bin 0 -> 34657 bytes doc/en/qalculate_kde/edit-variable.png | Bin 0 -> 25241 bytes doc/en/qalculate_kde/function-manager.png | Bin 0 -> 55558 bytes doc/en/qalculate_kde/functions.docbook | 3570 +++++++++ doc/en/qalculate_kde/gnuplot.png | Bin 0 -> 14468 bytes doc/en/qalculate_kde/import-csv.png | Bin 0 -> 27928 bytes doc/en/qalculate_kde/index.docbook | 1528 ++++ doc/en/qalculate_kde/insert-function.png | Bin 0 -> 60742 bytes doc/en/qalculate_kde/mainwindow.png | Bin 0 -> 33195 bytes doc/en/qalculate_kde/plot-data.png | Bin 0 -> 35356 bytes doc/en/qalculate_kde/plot-settings.png | Bin 0 -> 31544 bytes doc/en/qalculate_kde/rpn-mode.png | Bin 0 -> 27762 bytes doc/en/qalculate_kde/store-variable.png | Bin 0 -> 16376 bytes doc/en/qalculate_kde/unit-manager.png | Bin 0 -> 63199 bytes doc/en/qalculate_kde/units.docbook | 3455 +++++++++ doc/en/qalculate_kde/variable-manager.png | Bin 0 -> 52390 bytes doc/en/qalculate_kde/variables.docbook | 631 ++ po/Makefile.am | 2 + po/fr.po | 2639 +++++++ po/nl.po | 2634 +++++++ po/qalculate_kde.pot | 2587 +++++++ po/sv.po | 2615 +++++++ po/zh_CN.po | 2604 +++++++ src/Makefile.am | 58 + src/buttonwithindexsignal.cpp | 31 + src/buttonwithindexsignal.h | 39 + src/hi128-app-qalculate_kde.png | Bin 0 -> 13323 bytes src/hi16-app-qalculate_kde.png | Bin 0 -> 664 bytes src/hi22-app-qalculate_kde.png | Bin 0 -> 960 bytes src/hi32-action-qalculate_convert.png | Bin 0 -> 1506 bytes src/hi32-app-qalculate_kde.png | Bin 0 -> 1563 bytes src/hi48-app-qalculate_kde.png | Bin 0 -> 3874 bytes src/hi64-app-qalculate_kde.png | Bin 0 -> 5910 bytes src/kqalculate.cpp | 6676 +++++++++++++++++ src/kqalculate.h | 593 ++ src/main.cpp | 306 + src/preferences.cpp | 865 +++ src/preferences.h | 42 + src/qalculate_kde.desktop | 13 + src/qalculate_kde_utils.cpp | 307 + src/qalculate_kde_utils.h | 74 + src/qalculate_kdeui.rc | 168 + src/qalculatebuttonwithdata.cpp | 37 + src/qalculatebuttonwithdata.h | 48 + src/qalculateconvertnumberbasesdialog.cpp | 122 + src/qalculateconvertnumberbasesdialog.h | 53 + src/qalculateconvertunitsdialog.cpp | 205 + src/qalculateconvertunitsdialog.h | 67 + src/qalculatedatasetsdialog.cpp | 506 ++ src/qalculatedatasetsdialog.h | 85 + src/qalculatedecimalsdialog.cpp | 55 + src/qalculatedecimalsdialog.h | 43 + src/qalculateeditdataobjectdialog.cpp | 103 + src/qalculateeditdataobjectdialog.h | 44 + src/qalculateeditdatasetdialog.cpp | 750 ++ src/qalculateeditdatasetdialog.h | 145 + src/qalculateeditfunctiondialog.cpp | 799 ++ src/qalculateeditfunctiondialog.h | 140 + src/qalculateeditmatrixvectordialog.cpp | 491 ++ src/qalculateeditmatrixvectordialog.h | 82 + src/qalculateeditnamesdialog.cpp | 275 + src/qalculateeditnamesdialog.h | 65 + src/qalculateeditunitdialog.cpp | 425 ++ src/qalculateeditunitdialog.h | 73 + src/qalculateeditunknownvariabledialog.cpp | 308 + src/qalculateeditunknownvariabledialog.h | 70 + src/qalculateeditvariabledialog.cpp | 304 + src/qalculateeditvariabledialog.h | 74 + src/qalculateexportcsvdialog.cpp | 186 + src/qalculateexportcsvdialog.h | 66 + src/qalculateexpressionedit.cpp | 1018 +++ src/qalculateexpressionedit.h | 109 + src/qalculatefunctionsdialog.cpp | 537 ++ src/qalculatefunctionsdialog.h | 89 + src/qalculateimportcsvdialog.cpp | 216 + src/qalculateimportcsvdialog.h | 65 + src/qalculateinsertfunctiondialog.cpp | 404 + src/qalculateinsertfunctiondialog.h | 56 + src/qalculateinsertmatrixvectordialog.cpp | 381 + src/qalculateinsertmatrixvectordialog.h | 73 + src/qalculateperiodictabledialog.cpp | 276 + src/qalculateperiodictabledialog.h | 66 + src/qalculateplotdialog.cpp | 789 ++ src/qalculateplotdialog.h | 101 + src/qalculateprecisiondialog.cpp | 54 + src/qalculateprecisiondialog.h | 43 + src/qalculatepreferencesdialog.cpp | 414 + src/qalculatepreferencesdialog.h | 57 + src/qalculateresultdisplay.cpp | 495 ++ src/qalculateresultdisplay.h | 79 + src/qalculatesetbasedialog.cpp | 63 + src/qalculatesetbasedialog.h | 45 + src/qalculateunitsdialog.cpp | 560 ++ src/qalculateunitsdialog.h | 108 + src/qalculatevariablesdialog.cpp | 493 ++ src/qalculatevariablesdialog.h | 92 + 116 files changed, 44788 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.cvs create mode 100644 NEWS create mode 100644 README create mode 100644 TODO create mode 100644 configure.in.in create mode 100644 doc/Makefile.am create mode 100644 doc/en/Makefile.am create mode 100644 doc/en/qalculate_kde/Makefile.am create mode 100644 doc/en/qalculate_kde/calculation-history.png create mode 100644 doc/en/qalculate_kde/calculator-buttons.png create mode 100644 doc/en/qalculate_kde/completion.png create mode 100644 doc/en/qalculate_kde/convert-number-bases.png create mode 100644 doc/en/qalculate_kde/convert-unit.png create mode 100644 doc/en/qalculate_kde/edit-function.png create mode 100644 doc/en/qalculate_kde/edit-matrix.png create mode 100644 doc/en/qalculate_kde/edit-unit.png create mode 100644 doc/en/qalculate_kde/edit-variable.png create mode 100644 doc/en/qalculate_kde/function-manager.png create mode 100644 doc/en/qalculate_kde/functions.docbook create mode 100644 doc/en/qalculate_kde/gnuplot.png create mode 100644 doc/en/qalculate_kde/import-csv.png create mode 100644 doc/en/qalculate_kde/index.docbook create mode 100644 doc/en/qalculate_kde/insert-function.png create mode 100644 doc/en/qalculate_kde/mainwindow.png create mode 100644 doc/en/qalculate_kde/plot-data.png create mode 100644 doc/en/qalculate_kde/plot-settings.png create mode 100644 doc/en/qalculate_kde/rpn-mode.png create mode 100644 doc/en/qalculate_kde/store-variable.png create mode 100644 doc/en/qalculate_kde/unit-manager.png create mode 100644 doc/en/qalculate_kde/units.docbook create mode 100644 doc/en/qalculate_kde/variable-manager.png create mode 100644 doc/en/qalculate_kde/variables.docbook create mode 100644 po/Makefile.am create mode 100644 po/fr.po create mode 100644 po/nl.po create mode 100644 po/qalculate_kde.pot create mode 100644 po/sv.po create mode 100644 po/zh_CN.po create mode 100644 src/Makefile.am create mode 100644 src/buttonwithindexsignal.cpp create mode 100644 src/buttonwithindexsignal.h create mode 100644 src/hi128-app-qalculate_kde.png create mode 100644 src/hi16-app-qalculate_kde.png create mode 100644 src/hi22-app-qalculate_kde.png create mode 100644 src/hi32-action-qalculate_convert.png create mode 100644 src/hi32-app-qalculate_kde.png create mode 100644 src/hi48-app-qalculate_kde.png create mode 100644 src/hi64-app-qalculate_kde.png create mode 100644 src/kqalculate.cpp create mode 100644 src/kqalculate.h create mode 100644 src/main.cpp create mode 100644 src/preferences.cpp create mode 100644 src/preferences.h create mode 100644 src/qalculate_kde.desktop create mode 100644 src/qalculate_kde_utils.cpp create mode 100644 src/qalculate_kde_utils.h create mode 100644 src/qalculate_kdeui.rc create mode 100644 src/qalculatebuttonwithdata.cpp create mode 100644 src/qalculatebuttonwithdata.h create mode 100644 src/qalculateconvertnumberbasesdialog.cpp create mode 100644 src/qalculateconvertnumberbasesdialog.h create mode 100644 src/qalculateconvertunitsdialog.cpp create mode 100644 src/qalculateconvertunitsdialog.h create mode 100644 src/qalculatedatasetsdialog.cpp create mode 100644 src/qalculatedatasetsdialog.h create mode 100644 src/qalculatedecimalsdialog.cpp create mode 100644 src/qalculatedecimalsdialog.h create mode 100644 src/qalculateeditdataobjectdialog.cpp create mode 100644 src/qalculateeditdataobjectdialog.h create mode 100644 src/qalculateeditdatasetdialog.cpp create mode 100644 src/qalculateeditdatasetdialog.h create mode 100644 src/qalculateeditfunctiondialog.cpp create mode 100644 src/qalculateeditfunctiondialog.h create mode 100644 src/qalculateeditmatrixvectordialog.cpp create mode 100644 src/qalculateeditmatrixvectordialog.h create mode 100644 src/qalculateeditnamesdialog.cpp create mode 100644 src/qalculateeditnamesdialog.h create mode 100644 src/qalculateeditunitdialog.cpp create mode 100644 src/qalculateeditunitdialog.h create mode 100644 src/qalculateeditunknownvariabledialog.cpp create mode 100644 src/qalculateeditunknownvariabledialog.h create mode 100644 src/qalculateeditvariabledialog.cpp create mode 100644 src/qalculateeditvariabledialog.h create mode 100644 src/qalculateexportcsvdialog.cpp create mode 100644 src/qalculateexportcsvdialog.h create mode 100644 src/qalculateexpressionedit.cpp create mode 100644 src/qalculateexpressionedit.h create mode 100644 src/qalculatefunctionsdialog.cpp create mode 100644 src/qalculatefunctionsdialog.h create mode 100644 src/qalculateimportcsvdialog.cpp create mode 100644 src/qalculateimportcsvdialog.h create mode 100644 src/qalculateinsertfunctiondialog.cpp create mode 100644 src/qalculateinsertfunctiondialog.h create mode 100644 src/qalculateinsertmatrixvectordialog.cpp create mode 100644 src/qalculateinsertmatrixvectordialog.h create mode 100644 src/qalculateperiodictabledialog.cpp create mode 100644 src/qalculateperiodictabledialog.h create mode 100644 src/qalculateplotdialog.cpp create mode 100644 src/qalculateplotdialog.h create mode 100644 src/qalculateprecisiondialog.cpp create mode 100644 src/qalculateprecisiondialog.h create mode 100644 src/qalculatepreferencesdialog.cpp create mode 100644 src/qalculatepreferencesdialog.h create mode 100644 src/qalculateresultdisplay.cpp create mode 100644 src/qalculateresultdisplay.h create mode 100644 src/qalculatesetbasedialog.cpp create mode 100644 src/qalculatesetbasedialog.h create mode 100644 src/qalculateunitsdialog.cpp create mode 100644 src/qalculateunitsdialog.h create mode 100644 src/qalculatevariablesdialog.cpp create mode 100644 src/qalculatevariablesdialog.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..c4682cc --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Niklas Knutsson diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/COPYING @@ -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. + + + Copyright (C) + + 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. + + , 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. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..042a3df --- /dev/null +++ b/ChangeLog @@ -0,0 +1,477 @@ +2009-01-05 Jonathan Stickel + + * General build updates and bug fixes, including the ability to + build against cln >= 1.2. + +2007-08-07 Niklas Knutsson + + * New Simplified Chinese translation (Roy Qu ) + +2007-04-26 Niklas Knutsson + + * Fix equals sign for comparison with approximately displayed value + +2007-04-16 Niklas Knutsson + + * Always input decimal separator sign on keypad separator press + +2007-03-21 Niklas Knutsson + + * Minor documentation fixes + +2006-12-16 Niklas Knutsson + + * New French translation (Nicolas Laug ) + +2006-11-18 Niklas Knutsson + + * Update Swedish translation + +2006-11-07 Niklas Knutsson + + * Update Dutch translation (Jaap Woldringh ) + +2006-11-02 Niklas Knutsson + + * Connect "Exp" button Exp RPN operation and add Ctrl+Shift+E shortcut + +2006-09-10 Niklas Knutsson + + * Ability to set shortcuts for meta modes + +2006-09-05 Niklas Knutsson + + * Integer factorization + +2006-07-19 Niklas Knutsson + + * "Include headings" -> "Includes headings" + +2006-07-14 Niklas Knutsson + + * Fix set unknowns in RPN mode + +2006-07-12 Niklas Knutsson + + * Fixes for old KDE and Qt version + +2006-07-02 Niklas Knutsson + + * 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 + + * Select text when editing matrix with F2 or Tab + +2006-06-19 Niklas Knutsson + + * Use localized comma for insert matrix/vector + * Display parentheses correctly with flat division when "Place units separately" is activated + +2006-06-16 Niklas Knutsson + + * Fix add/modify series on Enter in expression field + +2006-06-10 Niklas Knutsson + + * Add "Engineering" display mode + +2006-06-01 Niklas Knutsson + + * Polishing before 0.9.4 release + +2006-05-20 Niklas Knutsson + + * Use icon buttons by default + +2006-05-09 Niklas Knutsson + + * Use KLocale functions for decimal signs as, kde sets LC_NUMERIC to "C" + +2006-04-30 Niklas Knutsson + + * "Convert to Best Unit" and "Convert to Base Units" was swapped + +2006-04-28 Niklas Knutsson + + * Fix function editing with subfunctions + +2006-04-23 Niklas Knutsson + + * Update documentation + * Update Swedish translation + +2006-04-10 Niklas Knutsson + + * 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 + + * 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 + + * 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 + + * Finish RPN mode + +2006-04-04 Niklas Knutsson + + * True RPN mode + +2006-04-02 Niklas Knutsson + + * Documentation updates + +2006-04-01 Niklas Knutsson + + * Handle custom condition in edit argument dialog + +2006-03-29 Niklas Knutsson + + * 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 + + * New icons + +2006-03-27 Niklas Knutsson + + * Check capitalization + * Dutch translation + * Do not enable system tray icon by default + +2006-03-23 Niklas Knutsson + + * Put selection of number base in result and expression in the same dialog + +2006-03-20 Niklas Knutsson + + * Calculate selection (-clipboard, -c) command line option + +2006-03-19 Niklas Knutsson + + * Use Escape key to hide window when tray icon is on + +2006-03-18 Niklas Knutsson + + * Fix session management + * Enable system tray icon by default + +2006-03-13 Niklas Knutsson + + * Do not do any unnecessary result updates when loading meta mode + * Show original parsed precision of enetered numbers + +2006-02-11 Niklas Knutsson + + * Do not use "Read Precision" in plot + +2006-02-07 Niklas Knutsson + + * "RPN Mode" -> "RPN Syntax" + +2006-02-01 Niklas Knutsson + + * When in RPN mode, do not put selection in parenthesis and place operator after + +2005-12-20 Niklas Knutsson + + * Warn about denominators assumed non-zero option + +2005-12-19 Niklas Knutsson + + * Update Swedish translation + * Update documentation + +2005-12-13 Niklas Knutsson + + * Set minimum with for entries in units dialog + +2005-12-13 Niklas Knutsson + + * Display AND and OR with lower-case letters + +2005-12-11 Niklas Knutsson + + * No double quotes in in history from set unknowns + +2005-12-03 Niklas Knutsson + + * Display "x < 3 && x > 1" as "1 < x < 3" + +2005-11-29 Niklas Knutsson + + * 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 + + * 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 + + * Do not start command thread more than once + +2005-11-24 Niklas Knutsson + + * Never display 1/x as (1)/x no matter how deeply nested + +2005-11-22 Niklas Knutsson + + * 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 + + * Do not display colon when argument description is empty + +2005-11-17 Niklas Knutsson + + * Simplify menu item + * Algebraic mode -- simplify, factorize, or none + +2005-11-07 Niklas Knutsson + + * 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 + + * Fix completion with or after unicode signs + +2005-11-05 Niklas Knutsson + + * Fix parenthesis for division in division + +2005-11-04 Niklas Knutsson + + * Fix compilation with --enable-final + +2005-11-01 Niklas Knutsson + + * History enhancements + +2005-10-31 Niklas Knutsson + + * Remove word wrap in result display + * Fix scaling (font size were replaced in the wrong order) + * Polishing + +2005-10-30 Niklas Knutsson + + * Finish documentation updates + * Completion fixes + +2005-10-29 Niklas Knutsson + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * Fix as-you-type parsing with " to " in expression + * Display as-you-type parsing with warnings in blue + +2005-10-17 Niklas Knutsson + + * 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 + + * Change alignment in entries in convert number bases dialog + +2005-09-30 Niklas Knutsson + + * Fix round halfway numbers to even menu item + +2005-09-25 Niklas Knutsson + + * Also process operators entered with keypad (ButtonState) + * Default to no system tray icon + +2005-06-16 Niklas Knutsson + + * System tray icon and close to system tray option + +2005-06-10 Niklas Knutsson + + * 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 + + * 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 + + * 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 + + * 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 + + * Do not recreate the division line image every time + * Add web address to about data and change bug address + +2005-06-05 Niklas Knutsson + + * 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 + + * 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 + + * 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 + + * 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 + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..02a4a07 --- /dev/null +++ b/INSTALL @@ -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. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..8a2284f --- /dev/null +++ b/Makefile.am @@ -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 diff --git a/Makefile.cvs b/Makefile.cvs new file mode 100644 index 0000000..4c0afd1 --- /dev/null +++ b/Makefile.cvs @@ -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: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/README b/README new file mode 100644 index 0000000..e69de29 diff --git a/TODO b/TODO new file mode 100644 index 0000000..e69de29 diff --git a/configure.in.in b/configure.in.in new file mode 100644 index 0000000..e44a80c --- /dev/null +++ b/configure.in.in @@ -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" diff --git a/doc/Makefile.am b/doc/Makefile.am new file mode 100644 index 0000000..b2f80e3 --- /dev/null +++ b/doc/Makefile.am @@ -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 diff --git a/doc/en/Makefile.am b/doc/en/Makefile.am new file mode 100644 index 0000000..d7d3706 --- /dev/null +++ b/doc/en/Makefile.am @@ -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 diff --git a/doc/en/qalculate_kde/Makefile.am b/doc/en/qalculate_kde/Makefile.am new file mode 100644 index 0000000..e97402c --- /dev/null +++ b/doc/en/qalculate_kde/Makefile.am @@ -0,0 +1,2 @@ +KDE_DOCS = AUTO +KDE_LANG = en diff --git a/doc/en/qalculate_kde/calculation-history.png b/doc/en/qalculate_kde/calculation-history.png new file mode 100644 index 0000000000000000000000000000000000000000..976cc59612d4b9923c0039fe69a6e46f8123d7e2 GIT binary patch literal 52992 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 literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/calculator-buttons.png b/doc/en/qalculate_kde/calculator-buttons.png new file mode 100644 index 0000000000000000000000000000000000000000..81b6f74afdb89adeb3dda9e79b7b411a95b8bd23 GIT binary patch literal 85174 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ä(ceSH#+(MCW)jlUJTESpm|W?8keywCEo6rC<6)H)FkfkD zZ@blj9y~CBo{GQ6oMf1oVt;+bdpi({Gc-(-F~NkXMjMrl5O)5Ct}Y3< zb0Go;ovIQa(dMQpZtt??C0oQuYH5)YaNuPW|MoP&7j)%{$(5;!p|y$sC2VlHE0nAGD>K%x9!l!(=pBYHn*kPu>{>*jL_n zdFkEnr>CQpd{&q4NYO+$PEAhMemw^dqh#lz2;U-G6URL!HxaS`XRs`XClAYOD$+^P zew~GLAzqmY(wNe}G}XZYwYe7gFflP!^HX-t`5tU06kpC5&*Pe3-vXsP2uDu<2vjQujVTaU)_>Uvv+ui3^oHRIKLjbMxH+p)EC zr!y3>xT$eFW65H~cj>_?TGrZ%^ijg}3RIgq|9q%X%T(w5dWs`<#$Oq$Lk_<%0ABOb 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

@pl*NT^5urv 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

`}VVf>32^@Sdk~1z}cA>7(-XtQ3 z!ix)Dmn|feu^@i-a~tVn{JIRI!?$(nTIHOoLq+;AWA*5?Uv8uVWxLp;gX1?(NoXP!4Ma;alwy~S%2t7);A2G3>70x=*v&u8VKOVCq zQh`WzZ1vVGyW*^F199EkTn#aAa#l-bz9cPr#Z>!**@e!heFl@yO_?G}QLmJ|=T#P!1|H6O*J03FQn_ zD^|dwzom-23+j(y0~fCjGlVjDiC_Q$+e)%}#A@m4F%GESh)~eq8*9Q7rT(HK2oKmI zS0f3=L?R@lNDz5S=!Hk$ZC3y5@baQZ0x7?u=GuE~^5na(hUhRcu_?fM{IDCrJl7Pr zf*|sBWxSAtuO0+-cGTDV3fj7Fg3+ooqHz^*1FMWpE-^eHQ$mCQ5=_giJ!S>wc+WWJ z9vkfrl>D`RdQg(hFBFKT{@)_#nmsln(x9u$&i;2m>1Ua&MjF}|wAdmb9&CE`vyRB+ z?s?;wsG;13%geW#9zS#_VJ7jB@|7~qxM_wpl8gFpVlm-x z=HAzahNqPhz0CK6S`80IO@)Ve>LTfi%GK!V;^&mF8FN)~zd-hE{){Qn}5WJARQk6eyqA zfvdkRKRM^qZoig-^{EZLH?CjLo{PJna`v&uu-q$Ql~qK68B2Exnq~Nn;xT|j=ISZ;3BNdek%@Z%C5Xdsd4p5Okcy`#02n!d9~@3d$i`QB7S z8zd}n=H2tcz`H0aV&pZM`^KX}LYjpB_1D%wJoOM~>EC|Azqs6+Z3uDcVawJ}fb+r; z@m_w`GJ9Z_q-t@Z42Qkkha^H>zYgOC1X8YGtDHDNT}y7Fc)m0-f09OhAxU=5U7Avf z>=!Dux3Ea9_1o(Kb5`I{z-mK<@I@1U7b3fylMzbyhtC`=J$ZHAp+XE~8n=I_R2@RO z38Nhx>^0hul|Gj)54zG^sA!gE~M9I(Zepo6&xYOTy zMi4}EI_^Ad%tYw$)s&UdIdQsg{wH@6d5Wu#Aq*4pr?sret7bN~A%M@c#Z4ZUE!*ZV p>Nr05+c|%sEMR~+0i1eHPR?@M$(51?@F^gOT~5x9_qX{Z`~~_a^mPCL literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/completion.png b/doc/en/qalculate_kde/completion.png new file mode 100644 index 0000000000000000000000000000000000000000..38d4a0bc1bbcc992e1ec7f38c0ef62752bb4af8a GIT binary patch literal 22331 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 literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/convert-number-bases.png b/doc/en/qalculate_kde/convert-number-bases.png new file mode 100644 index 0000000000000000000000000000000000000000..6a721022b7657c469a6c266ade64fe73b5f4c719 GIT binary patch literal 15880 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 literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/convert-unit.png b/doc/en/qalculate_kde/convert-unit.png new file mode 100644 index 0000000000000000000000000000000000000000..c341f9a5ed0bd98939a7beda32ba38f9c9e394bb GIT binary patch literal 12989 zcmb_@Wl&r}lrBj~@E}2g2X_VwF2UX16Wj^z5Q4kAyF+ld;O;JiyTicXd$YBFcI&;Z z_v2MfO-I0_;jA`A=+ill^y5)8~6SKxCD{0HEDC?`(?2IdQl zq==x3Yx-%1izjB^;{e!$A!!{UhvJ(M0t4(@|425Z+*~Eh0-Cq_Ps8f@P-Vfc523|h z;AyEzzw}kI2_7&NdziEWCQjn9AJVm#WQ^{0>(oPX;bEQNy*@cHH8rL3 zP_nmYfw2x6k4J}xeJfbMzqqW4@e2`oYyCV${j5U#t?#!le~|v&kE+O^ko0|irMvUk z!+Mb%Ze8FFbDq z#P7+6C^Kjq*N$w!Z%c)mrRp}bqDS+yUb;G#X`?%ocra_a16@)-dHF2$J-i%pE?DYb zVylqo5X2)R-sM?-lE;IZ+09Z*PE6aKiGARiAiti8fqI-8M0A05d!prD9L-K5vs&N5 za40))dNL=Re_Y+rl9FpaIm?(r|HW8~x;&=NYLvpq%JXK@Y2J6ZnF3TsoG>@vD(jRb zR5Gm0*8OUf%)d`(M49h37&7ZnM^NwY0MT}MFu{)Vj%3|!*2f+H{WZ><-N`|8t%`;1 z+GT5vME1gIF8TD%QEjHW8jcXp?T`0>9RcsrDj6yrf~JX!FOzec*Pm%oI?}-m%_z9d ze8tpL)C)WEu7Q{!A+O}-7vx7qlfCjqs!kbQYsbf10jr z8&7cJ+-^Vd^QJk{bXJrK(I^wp>6>XtDJ%$o}kGKjIl43ole z^Fc+aB}Nr0Q>$S;!jSgi9ZYF*C6~FTEn3Gc=<{|K=88?Ja6?nK9AyB zJc%i4y%Z*F`cVPgnV`Bd7eJEnbm^$%urX`gKfd}324>F>JES|vrxT7c6S2%IX)Nk$4GN0H$1RiW74+Nmri^- zZPRFCMJSm6^P$Nln9BB}1?;y>;w&+J(n~N)mXL^NvMhy0Xs>kLhE-idflnL7VeXJgy_G6P^ng}3pkd<48CB{&t zQ=A4}OhaAlk(KYSOUBIQ1o&@1i?m<3)V4_1*uF_CGz+CX-0^&B38z*oG~=&VdOw(O zy#r;Op;#pR)dxNo-rNXP&Y%n&prl2SK%C^sRF@TZFc0r(7Tu}Q zBg(2uW{}|_Z*b?WxxTrdyvM6Q>a9^6yKriCpxQjk&oy6z^E%ZInEz z*r)vbcGOdXzY!_rwy&SC26@QTd26n%Xw4v;d@3hKusrF-6)hnSU(UNbJ6eJI>#w(x z1zTx+3y1Ti{OAlv*Dq02c9#wx0%E%fpJlwci!s@*oQ#Cd-6fjM%lT8COrKOFJaq|G z={*Z+1ikmj?k8c?h2H5LvU%ZK;8gu)A0f|LiBO+8Gr>_ee2Seo=`GWYGQdHXjQzYi zh1$H4YH)KZ;DzYP6C0vZOso;^P)h`DGS^@)#pSobQ|5P}!fF>nB%F!o@jg7~G(dYg z@+L}T!eZXKo_TU`q=P~E`)~=l-t&=BF<2S-Gh863(W#_UN8i=3NPKy39tTeBU9(uj z%E+ZzK5esmcO@8G92ejF71V>UL2S#P5LeoXLb1xPLiNOljQSv_+Y;g@kA@h4A$jU= zM1Vl6n(h3pBMLC#dy3BL^LfoiOOej0m zo*LbMg0;fs`M~lK56kd_KdZ?%&UecThD&>6R$*#PIWD@~jflOn{1S;L0pukY4hxeV zF?7u>p57}iAL?sCd98DQ2UL4%^dtZL@WAAVv)$e*&e0G0ZW4afjp77m6X>pq(2S&&pFxynrqQ9!=IYA9=dKM{oh4`G6mWLRK5)OnBT zLtR-v2iqs z0O(Ue|B|B}gXh%X#27XIZ*}U=cMvWm5D}#S&$|RA#ok7NpEu?bcU&q_|jd3*zXxGya9auHjbACY{Y zcRYQPWHO-Tu6Ys#eJU4yjj*oupX#8n(xP-DnM5JAP3;KcVc*a2tC}tui)(Axq&+-B zdRkt~YEZu#8_t;170WSG&OJQ}Ryq#OcckVFVj%bhvI?!Jr$ny*Df} znm71V+cr6nk6qnU3ALI`USpana+wEC0cs}_?{lqr&jR*akQnhqJ9$bm!w)y*lWb z<#1EvDs|+WQzGiQ%Ic^DlTMvO<3F!+4zi;iugyCYV%~O@y)2ZE*b1vdWSVQ^_uMgz zV9n}{wB!EQ`*3naIYTcFkj_t|#am3oGlVx#Z7;vD#wrD#eC?2ivJq##uQ3M89$St#UdI%!ho}4 zjKp(X!X3PCE_}!Xt@loGpw(M4VB%55YjLP(sROTVR^f1qs_B+odq?2{r&Ro|QU#gPA;x0p08B0F}Hh!wF2jLg5W zA}@Hz%o4a={9}iIzkAQKwf-WQHXLu!`7?VY#wP4Fps)SH^HqJ~YxR&%tp@I6Qi>tP zpAt*m59jUI*mZD_OwO=t^I3f5KeK(c)v7Mu%i0(VJNthF!EV1my#7jT!%T8N4 z-?$=@ZlzW7kXac*y>W}T79RG}+rOr}amn99+P{7gRMMh!*JX5XA7@*fIfhUZ>M9l! zM$dlS+cSgpox4W1%PJi-?!L*2Fb%Zt*AHH^i znp2ZQ>*?Bb>bxtE5bLo6mOZhe3(SM24_?+0Y%*5$*f`U5YNbX2IO6@kL~GHiVc zV)|CFS?MuBRb_!DZ#s0u!lt|5OXjfY=)}{qeH;(0sR(_Zq-aKxR+{renP z%E+}K*cMJ8OJnjUUyWVIx>maJlB3L{>_co>h`HJ}$&7FpRX~Pps3c`waaSHA)mXH4^&qMojPo4=|X{;p^kFau+-SNVYn z@q&Gx7+Nwwjt2N((Kvl04U!Sw4GiCog}k{AWn4|1l)+~Poe(qhE-JD)PY2G3>kw|o zdzOw$i{)7tlW+JS%E|})U&2W?4nETICJ~1{ZD50tiJ0R3t~F_kr5VrQrpXKbf^!3aAY)dMN zza4IblhY_*E)EY537=wp6MoeSKL7hWSLhJ6F=GFO9#5E(mu&mylMRkK4Sxa*^4FDjH)HC zKKI0Xw}Q=I=w_x8N;+^;d?-}y;BJ}y6}{>lR#NeZOK+Ekg_|LwX%GyLO#HodP3a^} zZ8+X+`0CdL_Tx|S)d=q>trreDF^&&XX7UKm)>@S2M!KCpbN|)`FM0&Bt6wSXgYSjo z2_hm5TafCM*m^bhyPoe)OI#ihZTG$Xjatks>ASZ>;CXj7YegbpUlKN6;CzZe$I zN{idsE@oo2+DtPmNNdcrlv`^p#52AdI@F|p`5{0nuKrEY^Dxs~G9e&_6|o^>%s|JM z@R=JnPk}nxIEC0HLumUbfSe`<6EE?+MN&ie>uK8DcA5z!^qyuU+U}X2D1t|`3LFgk zx;k8F#~?mG;kG;*nR%W;uen3<^9rRV(}v`=K3`{D{Z z^B(A9R&#i*4=Z^<=-R&0;mY4Qc`5;ewWjx%y48=A70(H<3y_^{=FL8-g4a(GmVWF{ z-lQopy3dG2o;ZzquFC_{qWSvLs9_yLqFXj!$GfiD5&Y+rXDUl}4G{t9cme5Bhe?IC zP82=0651Z}w7zfa4i;nKgz(*rWUw?WG8p6LrHm>|S{h*R%A*Y=ECzHCDoTWoIt zCW`Rh=|;74$BorWbl^)SCs(oL*x;U{&RZV>etA7HjC-!eW}0Rei>WtaP8G6AYA6?u zPUKvCVO~>q^vg|A$3rPivj`$erBZDSAj*zd5wXO`Q>st6XlnSs+NbPRn-T)0{Q@Ou zzfvdU?{pPUL^83BM(A0;D>*)nB>#~-9MU{0-)cB%T#z>+$KdrKnyA^rnmOdvc6sf{ ztmh%YTaS{J_o@UmJ}>ha60ozH#zgowPu9*af_Tmvx_K%Z5A;^6}fQ zS+bJWpHps4bA(kKykBA!J6m()YERz&&D#;Ei}WE?BJPagy3XN(*6D|Y^U+<)nbZjw z%t>3CFWTf><{Wmz&11vQ7@9N-pBGEe>)UmPM#m{0&hg8a?ZYXQiRj>ccf$sMSEvt3 zg@N`~+7M7NX-zMR@;QrE#|>vq#c}cWwEi;7iY8?Q4o|g56Gtb-_%HXZcn=&BeLu!T z`Sv}?*SOZQ2UAwlYI((5(wsteD%m>@a`JV=Hkcmd9fEKIwd3}ErrcW1wmy7citunE zV?SLPlayetk(-oc4eg-}KuqXIPpE~%k4QeJsx4jV7l+plX2GSa0IPGd<^llc}O2S^m?p(5}eSv+VM1emBPc5Upj@5k^Js zjPnsL$N5T#R%0_K>3T>mm<&WmsH;Y6pZVi!aQ=MubW4sMM6AR~Z2QEz-CMZ_vfAOD zdJ>;D*rGFIQ+7`m%*Yy%KAU!6KRsn!FjE(auP;OF-&&j4nag;!cb7D%T&!TBqgY!1 zWyGjRkLqz=)lswL%Lp}_7QyQCV0fn^mG}7i-lgNEVB+;qhf_-1sET8X`GM0?U!2Pk(7uXo@^L3x@lgLkfQjm)13G1@Zc?CfZ!Jj1TUM9hzZM>rjkmeG--gH zQxd~d`;=oR-Dd?!N@ChWp@s9=jz7PK8A{rzQ4{>UK@mwvv3gGCUUl;lRum}xngGde zIw*}lvH-tj?_|{Y2`5=1c51Tnc!nhf$Hv~~Ioj;ZdTjoZSoQGn%!%QQL-C6Op89d; zl9}|gShzIhId-g8n3#2PpipAS$Z!rgT-Jy}S9E+KXS!u;o|B*;pD8$9DWZR-vx!9g z+R&ILGgjn~Ob4N?TBS8Li2++)@<*Jlf_pke!E&LY#Z;6<#HljdZmss(DNd1$0F(r6 zm6aT!Kr2kSqMv#;a5r26!`=p))6za8&6Qa7mf!3foNO+^oT=?UPLp$tP+qkBMl?Y;S$Dm$QLtdG~4u$8`$WOP7o-2Wf(h`~Xet69JniRYcFOKSF#qOs;R$WL z2bKvWh1L6l25&+A|8eMy?g|2d%FJu%lalqOo?g}3+S;Ox@AXr|H}4nsCOc0OftSGYZ{{ljq-T zzgs6`WQ-gfl+e-D9qYw93*U)&rJ|yWOHbFyT{~TAWVPE8DU?YO($OKHQ?J~~i{jt9 z1N(67x}CS*HMw0=N+&UX)m7+#ZXwyMHg$WPx0{;SPUVVv-Y%IwT~7$mYd3`7U+-U! zfI5>Awtl}ya=lw~X?DHLm87@6++H%xDzF82h=_}S!oeAUBlhe9RAJ!Ig07jU+3L(d z>~(`4h6CEm@_G3&6iYFhC6I-J&mPZp2DriAm-n}?Rja^(2Pbis_F2}+_0?4kxAB(| zmi6`ZLPx-yx94E_nL=6FLmC>II*Yl`ktEPN%n_gCd4?I={>0v2Z{B?t@a9G3hi22f zPUVTa9Tp@lwtF;|boBO$5V>x=No3Rw70TJT-_J4ymVrW{$-{1LZq+|}KAg3l^D8(1 zQ;zLAZ-dp6!PRw?z)QCEN<*Q24gK{+4{Fj;P-mw=Oiavdh4zAhwv;qS|NCs0^Yyle zqq3XBnE@5>e1&!jj|<~UqirM2SwpWn;PBSr0!vBWyW}B7&Z}u$(2b4nGp3TU7dJQL ztgN+voudeO`Y$$n#%?8J{e^Ov9?y=CN3M29aJlTs@gf329niP>`e1`wQc}{<4wtjl zlsGE+)Kkl~7N_Q?&wTD|?d}kRjV|9h>y^Z_wN~XSJ-)cf#6-R1nIid_dQ0_MFWpvW zF-y)4)YiX69;* zbu#hDjiVzeJv}1zN*x-P4BCWJ4G*i!?TW^A13&;av&mn8wr29gQTHaYY#rR)(DEF8 zH^2e9Vi!Ol7!E`dBIB_YYb-|+^1ve@(KT92#zq@2QQ9G*pit1#hBE55XpE7KurM<- zw>_SzgZB$?^r;$S=~gI-Bt}k7j(=d_TQq!p zz(;jmcN5gDq(Cy)dt*zDw))Ka!a_n)5Y;bevpOd%zq7cVXsbG3xR2*6$Vf=uWXOpd z7?4^nRPI6+^i7XuOLiM{i{uDzPnP`jsz6SBPk;?mm<>M!p%PP4Q3ZvEBRik14n>m) z%eb+yvf={Twrz)CN8o)WWn+s!oGD_pn5DM2w-2p99*iN|+1sz_!oReM&!-S%_3rAEXKo_{So-;rB$Nn zWoEFyQ~dxHX7IR}><%Z;YyA1Opyv@WJFBv~wuXR;Y6_rB9S~lt4W{GiL;eV#n!KO6 z0f=jQX%&wm8cqEg)(G}a18kSQaEyS2#QJHMM!67;h-iGH+fVjUEQ)B%_Z?g^i!mY+ z4kO!X7SoTnfTeZ;mjj$SX(*10_2}}q0v#J)h0WgX8V8#$T6$=GMH>;jwzUXlD4)T^H9vZ=nmti4(rSJJ#ePC$yNvt0NnE-uc?%j6Y_hBT1n}&809!+skPr~wWUEzZwY|PP!otF; zsLlM-kCp<>TLFhX8RwJ5ZhfEUfV4F2YRA0K?<8XVi;AdV#?m-I4FY6j@0eE6MMOp4 zpyA0D+PSYiV#RUk9v@9+QfXqLwLeBGLPjZ@X|*qdx#Z6aPx4zTu1 zgi2@^DlUt^)A2mBK`;D#xu#*G(-A(0jnQPbpmQ|^V9KuT}oM>Zfx>+}$bOJQIzT>m`_U<+QCBLdE;1;+}fVfA9k|Mv7OH9JtD@?O9INl7M6 z?PUQmOuz;M@Z*{vF1`!L5EF13oB3a`&#U#8%AP)P1S%c^u|!Fm}yZ9Uqy&_c@*cPwY2e~aIWk9H#gf}@DSw*foMD)@K(pN0iO zWoG@6gq9!yK)c_*`vUe&XtfG}^#)KMi-r+c=(m!Dq$G{Y5+Z`9C@nUyqu?&--v3J> zr?lB9NyOx0MK3D-ZC;r9bE4%PK%3- z4o5QBF+?CDv|VP)K27)|a*-6b&_6gb|C)<5!MuwrG6;@%-nVHnae4a=f3ijt{+DVD zj#md~0R$br_DWGp$2v#otaSJLs`m@(ZaDMAa zhL`4_4Kf(52KZ{)i`)sEqB?$312ulBurdY}*HE!UVv}4o4Z0v&(u-R=5rwb!93h#f)>vL0ObrNa!J3*Sq;K_KKJf?$WT}EZ z$L<8IcAlCYj7&|HTb->*Nx4}a7iau~R$hLRWcvzK+bu+sm*{lB(>pZ6diOk>YqTHX zk7x3|`&Mf*=4t`0<$dY>Uh5fwH@kV>R93i6Kf*F3DH-m0YyNO^I^aXqu46-dw%13` z#}~nvf%5Ee-XRP?k?LUP*Ry^%yGF4KpJxb_zE6F6ad93H8JmZPlC8I=xcr{5Ypr+1 z(bgWMBP_meoPrJ#JTE;Wz|KR4{OGMl$(YQ}`@D2)xz| znGn-^F@kF7XPEvl0@Bl3m9;1@Y-+I4zgeftrfNiTHcln$I!3o;X=e z#+W}9|ApvuI!B=Q1YIs}%QM;h?L{PfZKb&oc)lUybH5Q1+uP6b*(xatR3FrnRJk2& zu6eJQXpHR%edF`eoFVy|HX4M)-@UYylANqe|7^uPflRDbFs^FILx*=~0lGL|@EO<~ zq)tyym!&=o1rV5gte(RUOY(cU{~ znz^@xPKJB^gk*fRpoMQWral#C3m7k%1)^%CY4QT+fXjYzh`2--a>RJi>ipc-V6D9f zeV#C@*HR`nUu!|hV$=hY3R2nZjl3!b6tT0k%XMS8*3H$`9(u8DYwG8~P@d-CUxvGDG8T4e!RC4=|!k9<=KhHyd(! zm|hh}f_A+H1)sYkB`5W-Oum*sCS#2zhbZrkfeeT5X0+kw?+-iEr07+9^B2F%vT9;y zXUNPQax#nr3jeXvz_7EsoA5d6uW^5b$GA$r79ZA<)ft?-S4!hoaOGAXj{e`FDFno& zZ;5vHjs{y{ue&R%;MFD6L3h3)`3$4QjRD-R?#Ov!0_v45Vb;c&&?_tV_RQ=32>>Xh z1|l;KW@&!!>=-fXaO#(%Rsaty00N>BV1BzhLoe5FoF9#>=M6ah{OolVGO*a@rp)YP zvnEAeCkrnrDVeY=PHXUZT&2cz*_SkFQIBmMK`bzZ83%>BuDfo(nyr^JpZ?XlUVfD& zBim+oZ(ql(CH8@4zCnc)na2gzSuDk0Zf8+3Gv_3)W6pihh7|u?J@0Q;$8bi2UU3-R zrZ>9X`@9+-L=U9AcI&X)=*U~06c~`!Tkh-2WL&X;IyghNspM*nhFB8m@8c`9+0)*4 zyP`>tfJRt=-obD$d?AI!m|JncP~&or<7BNB?pIh+%&tW)X`Y#VVntKzk!SXm>f8_<9zn2n!zbry>+m7Jiay}v7A0J2^)?Vgz3jMzR zNL=GFA?SYF7G*4*G|83AcizUA#%d~u69)IKNDjU2wfnb$@w%7kN1(iHklv@2rlPAl z{WK6YlcVfEcN0lS#%aepJergzPKx_-qd?gK#h8fvteW#MvM?Vy*Z8A{`vWSj$pgR9 zAQQWlhWcpKM3Ptk6RH3uARsoq#^B!o;##-s^TLk#RB+T$CqM~Had)MU9EJTW8GKZ-xqmaa4K z6aLW*j;w|srwS!1?0pDb0P=ME1=X0GewZ&``=yolWAp%>_hC?2O?d5 z7j?P7Z)tgG*pi2Vp+dy&^5TY^fnjbm3Bas_t1Gkl^5(T=SB_=c5tjRVZturaoDV4O zt97=M+wvF3RRVEYRjk*B^W}~3DAr+G6@{{C3hU`#gN&sG=n{*7fv`TZwIy>D{fOi7 zy5H!iOm3ch^0;qX8?TyAYp7`^uHvCxS@3CHoyzL!s`b^6iFH3@_a_A4`KOBt)vy#+ z(`vwgCT{!>uIN901YR$!tfU=Qb&O}OwaU7MFHaUoFBmL;8KF2jexD8|nBVTV9f;RdO)i!k6Y=^uPBGbf$mhWk zIfIlG+4|2`X8{)!i2A7Cjr{il4Y1 zj%eD}2gZ|0dHft496+0Ud3#x%oEabQpO%)Ea+)KLBA%nbVlrFnd39(i;&^6|WQtZ( z4&wWSb$re9`Vclb$;8XoF7pVy!K0uUE{tc~oH%8f`?TI}ni!xHt^2Z?8jKz>ro;V7 z9)R8l;86Z~8kxBN-m#g0oW}kvw&o5o)B2f14`N5~d~dL~wk7s*(VrpuI=2?pP<@fkrTd>;$eERh5W_(zDucd)qD~D2s zA_Yp!=F>*pPRMk#%@7g7C?J6?6+T#xfktXX(Hoqj%M)s6y(N`2WNXF5#6EPszR(GH zcKR+ZO7rqwDDuC0zL!m9uQd}-GzL0ZhC~FL>6=PKPq#W_j!er z8s#vb76CF(|FG@+#`$@apWi#~j7V&fZWAXQK3nUMGB@oTf-r7lMg8(6I@DWEpYv0K zr*hmrBIF~8I|c^EPnS-ImGxXvIyvlBtwcwB!!}4Ah0paK!(yk8k05?%k#wwxx3_oo zv!I|Xr{_U-NxELu{$!3H&;ivgI>shckLKY9aFah|dn+sEor$eEdni_hd z?Sd=@pd5`9Au_q5Q$|2W?(OdG{+UU@Brs3`nfv<~vHX3EIIklfJE|3ZVY;cv;R5J6 zcR~h;Hzx>Jh6V?}(9wkr4)#3RPK#u^TQt#tdvWv)&Q@JGoloEa$1*Z9`r~p=)Xy(4 zyhYH)aIgQF!&lR`qr1b)V`ylI62T#-URDJGA zc%WY*h~n-q=P*qsy2Y(lwSrl9GyOQ0%3*q)cuKER=l|$_2h@XF5mi8aL05Y)Ga+Mq zGF37>1K?e&OIF7}@LVbison(LG$c=J&q87mp*ZHJSKAdz74$MHpppTaFu! z2T4z<0xoVqFRASv97005O_=33-HF@}egI5RAHXwx<~1@4c^=LD2Z8{9Gt(|EpNV%% z{;vWqDJd~BHb%#C3YP@Q8ofNZ4c5ra6pm>;EEy;%#SRUR8Vy7WB=etQ)jm|*E4g-l z1#%ERWcOf7BJ4p)i7#P_Sb8f{ZmL|bHZuZ$p4oIf4G5HX6>8Ezr70Z5-}g!WBlA*3 z@WCjZa^dyV@B4I4JA!t-Le;YQa3Vwg37d5GY6_pbGd|bTdfd^p$B#IS=|yS`0{s!M zQ8ZpxJ0&t{>?zPR;K|FB8Pk^!-#5C%|B*Dqvq{a~r+7|Bv%B}z+n<@ff3Mb9#7iRf zewsUJW!ObbsumajBbFi}Z@WU^thk;I!Ttvx0mNQ|0Lcpj_iu1AFq~_oOX0U>IXpacb#s|+s9Y+v%68c^r(sdI+U2*`zxK~H8dlS zx_^5bj>tn=oN8obay8Jv(8lB(-gg5K)mO*1X}HYxn1_wFVB_->X*CndH1F4lH>hj! zd14Xtd(GNj{P}KZMF!*AUaml2#US)Mgv%>O#@Tp@sQ?|{Bg6&l0cJ!kl0GIAq8b)A zx2x~{B|n~P2O)VLmc)=hZE_)lM(+u-@6uVqVJ{{P6U;T({CNEScB8kX)_7Q7jn)HJ zf1Y1oiBMELqX7fgE!np7Ij|mV{bwaZ-#BvPb&Ok4w9ssLf3PI^nti#d?GR4zP^IvI zP{6HF$&&`u&qL{r^3@0~s1Mn{)>TdwqkVV}JgeqG3fp0i_7+s^ zNb9kjOG^UV;R)|sMer|U4WR=~a-bpp=fz)hU~l29j_0%A!U+S!D-9T*7qe$Qf!?|s z+gH4|e00^)*LJ25>v*A}Ks-vXz!Y0W+WG7$j@?>IQ`W`BrN}r8t?NtlTuN8hhdL|t z->t2!bG-kfGnd%laXR^KFQUL|K2w-*$f^BzW#!^+aUz3|jF5hYor?=c{Se0g_>OC6 zq4K~-fE7__|Hm{aVp`(mP9zbc*LnyCfJOgNE5A!a{yY8hzcZ5mm%GXBrQf!XdVa~% z-kDDQBU2Q(%yhg)J8(R3WT%k-{iCBeGZ~iud3eaAsV__c>#~XTRf& zd%xcguAytKC+0Kf{Qv5|j8ayVMnfh>hCm=_vN95?5C~Kq1OiQj2oK(&%F3IDKqw)y z5@PCJSqDp=`Z!ll2q&}V>}GJvqUK0P!O+nQ=!auAdiHfa{I&-66?h#U*3VW}{kLC9bsiBQcUGqxvR_J$)PBTKS8`~|f9g3v=SuY2`Os=AUB zKV}#$@nK`>epHeaPk2y7FqfNpcDh#ECD zJ1wF)KX)phgMETy_YIv&R7WJQbn3^+R3Wcsyc<6e`CaUS-maI8!EG&p9 z=2vipz(0VV!oe@}dz@@nyZOr-4LgWoFtk4av=Nu(?7?WF#^Y=DV1;;}r4z~=)@j3dPz@%i>-6XajT@?%$ zQRG4A9I#C!Er(7S&CAP#3>h=`VT2HhupAo^hB-4aF==uJXuNLsFMGWrrXozZ!T>qd znmoO1b~PU@2-(kD8I@bg`I(6k1Xsl+?v+UL=`kr3Ey7VlQRL*f-O&_fY!v zhVv-a5o7s{S1!qIok!2S(R!}i8O)0hKX;4M;`5HumPKF{kxR$VAuQ6cUVQnUX#_>~ zHzW~NW~o*0>F14p-upySqvPV|S8~Lw&+l8g9hBG=qOMf<_MEq!%tv#~3@}l(H~rSU z(g?raGWp0kO4m-L`MLB$R)))m{8jeAsjnp#w+&tvNj(%q|HQc)#+!NXj{pSnhxm2I z512&XJI0UgOpN`Ns7!`&)x1jOKi*5MS!s~k2NN4ul1t9th(lnPzOxq^2h4|wH-Db} z$@88Lnh7Bg>8$vNq4usiIRi3!t8Jr=!VmQ8=5 z-fsUk>)D^bXhblu!^Agx8S=jv*SkBWiBwkl7Q8gnJJs5C4vWUXcyx8)Ar2QZ%)9P8 zV`?@m?BgjOVzX#h&_U~K&-GbJ5SNJaZH?j7fDb0Ab^kNucs4h zptBg#W9+;U1%2N}%KCU3Zbh;REe2s;9O>UG@Qmi^4F+q(#Mdpm{%P&(O`!jsqA^46 z{!kJuMRw^q*Bj~CxEK5$$N`19G zPw;DX$1$Z}tM+u->Gp?o1}BhjS$q$;y)iLcyM#cH z_L}HfTU#jR5n8&IWW&$x(Bch$bk5#6u3tU~ia(hT&n{l>;_g93b{a_Xphi~Rcf<{czRx1cYsR`A|ukDR-2Irs>rcX+$z_}(A&(nD-k6U}K&nf?!R zJf`x*>PsDcbsnXi{W@HjIS){g$2Umco{UTcx=XJow(JpSGQ1$oN4he2DoWaMLh zQP|Hy+`{W`WRcoH{b1eZmOe^+Zg*JggnPntT>BS1ub z*hf1x4I;CtSVU5CLVzuy!pLSgfAgTswQJ!ed|aqpaMOMy7kh9N5pr;M&CN^#9mJ2W z%1FFO7`MkqL}t?stv}Yk0!Oy80Ow6M`eC+e@OHl;BB2GEA)G5LB6;x}zag`W;8H&h zS;%KLn+u}FVQ#}w)iWmJCo2`Bs|@nHJN`e+N6l|XRhRa)_x5cpgw7duKoyN%GuKN< zYq%v8Iwo8X-)cuEY+uLyQ1dc;t(!n#C;TlOl=9CPh?gF{jRPd2%9iiMTW>D#V4+?m zyRZ_9mP-kb-5(?4G86b_VIru*WztP;Gp@vora z_9A9E9bZ_!>(5x?^*ExS!()%#!HL51ryhTm52g8dNs`q{V(i5u!dbQ*O7ep!th-~smEYz06e)u^T*bJ8yzWY+&`AaUJasNyg!_8|JutN)S=8e6jOB$ zka0*|zRAQiLXCIo&k{KjqxP&7UTLPn;L&D-GHm8eeUuHJ>cR*)U;9?@=q}`cgI-j5 zOQz*mNHsVL!y$e7=GQxlg4P(4<)x~j{X9qC3r*tt{U+0XnWaaLMt`!Q8yYy(LKMim z^Nfz9fJ0tn7Y?dqxpC?e=Jw1>?Ay@0wepoG1nFZb+8a?!CoY{U4fnV`-+W3I6wJCH z3Ek4;93O{fn9G$Y&%6`#Fv=8ReQB{E2vKE`EfhpJn|bVynW$cFutX8vtPk3;VaNHy zw-X#1o(I)vKer5`Kzrz=ADC8ZH4Kgp?xO61!WKF>@q57y50CLDkt;Df^c=mx*D zawH4sGR%lOGYn36B(lU-TU#Z96c(V2Y(vzzvm=In!00NF ze?j&}+PCyUFMoRbRG`s8b81LV>X%6+S=qTQz+&11Yvg7#hp9udzPdg;b?YbeK$S#4 zT-lIWaO5-67Hh}b#Q)|Be!R~2y7@7l;m4fQxqWmCJA&Wkq`4nY*T4%+$=Qv9lolth zmk9Cg3eHMLK`b7Iec_(>V@-u37Iu;1WF1>h>Oa}?ef{0gt;2ne0EoQ^zsk-@EnmA} zdr8Uk_Uh5u)gwsrGmJ`k7-e0n2&tFI&`#4)LLrVOg?^!&G$J-1C9c2@u5haC%dxF; zDjP1Rj{+tVo-6ECsTz02Vo7TY?5!B*q?_2WJ6ka$j+|mbo(O}5&G(YkRt^_bGI3QZ z_#KR6)k!3j&;{8@10|N-3b)p?UxZzbj>O2GSP?^DuWC5ylr6v5EpO9s9fFNt5=3Le=C)s z4%SS@utHf~`^uncS+x|Ftb`+zqKIjRo+xKN_A>?Z53PR5%e zw{VH0piB(8K!aa3-aoCH$P0^^__Y9%xa5+lbPnukn|A*-RZw&4yHTHPjRjOGc=HAe)K2=Jy{(A7SFMk5-FgC{d6X*y*zO$`sO~kPpZE zBhj#tURR~zo4PEvS3TWv?`nmDKCB@491G83w&|A2FPn#)d}9^YgNQM|R^^0343gh9 z*_mC^3ID(=K$rW&AEHtaF0mE~*v=GR6Xq8eL~}-A&6>X#6t~loFZv&#A&8M)^JR_U z{^hmTo9T|`_jNSnh8bRFL(o0$&2=;+raM{$Zx3ohdJ;OT4E8qq#4$RoZ>;TKWIvt; zJG|3TbyI?pfYMH@hKrAnPh7Yjk#76ofZLQ)5&Tmp9zub!s76Pn!Y_vT!fNNxt~EK+ z^t3AR`yY!NDJ&ISDlAyu*Rd%0pfe}Zkx|K*1!>+n2}xk(mq_Y7jX(zUqclu66loq!cNDiAINC`FcDW@2=m27T9jT~oCQG?qRR0-Z~Bk8-XDmi zLi;C=$02=#!0bxJK^Qkntgyo)OWReQ7X(q=NFfr@kShMd_R3A21W_Z5FM}z~whbY$ zkJ%$q_L3Fw2E;95xWPLwJ64|*^`#UIg|o&WCTO+%LQOYv&IW0*GPICo3!RxQ}ky{MnJZ zXq1SA9go;YM$yv-35>reD9qm-E=Ac&heBwU`^T!7bttsHT^kgE$%xtRd7QW3M=g$bdmO+>=W&iHDX39QQ=1@Yn@li| z-BfdPoGs|{5=W_C)%Z4Y;Iwaa)``a`8Vrb5Xgc>#2>g21l5cP?O!E6pHCtd8wU zEFE68<%PTS5P-bw9uui~-4@aqv`L_Az>TzlBpJI|vx6Pj{g)CwZ z!bUv}`^oBXFN8iuGA{;3*QelaeM(NnXrhORwY#%zA#u!(MPtE2b-BCG)>kgdgi$6D z7wP$7$i8s;ixj^2;~e$pgp1yW>WMl7&v`5=0AkZ$KS=cz7=kDvRPJOaHUrH&xcLHV zPmc+ciS+xTm@mN0f^GV@9Rs4Bnpv_ydlT;8M(%*Spcuhok?W|Z8m1Oo9GlliNZE`@gg~^sjDp^eM_mroJ|kxw}@$WW^4N4TuL83}5&SqL2p! zyj05TLK=Qq`vJB~r=T|(4$I2vh~J{LBTQ?6s<6Kj@hwlZ+mrs)T!bU~vShK;h!rUQ z++1w_$!SF93~xfd_%>Oo&tmCWwCCGm=sv7&OO%}-mOtO#bkaUO zBmI5h!V@EDJ7+_I-pK64C7&k;fic=X<#%hCEI}`V{F=x08V51~E*JXQeckK}z$W|p zJ^kX=EzP!#=PrMD*JFb<6>P|~RQ+cu!2BmdBIVEu9A@xjs-sxG6QfJgQg;9?L~)sF zYg@-EkfRMkVJ{e${$97h(u>k3!;n8jS1o9?<3WTJkpC?IOwq)_pKXSkhY^p)cs>-* zt2LWRaA?ayKIF@kVCa-P>%o3!&qnVo!cndP3?Fp{cV~kFNg5+lwCGF)iWA1J6{ir* zDQ~OpC%=eyO*-E2ymrHQ`U1@xYwR<by3hiq6@5_Aq!?2voW^wN!;*aNk10>Oo!0;K;DFVLSXQ z=EYvUv%oio{RX&y_GU_ZFBtHz6pP?{@CVjA5JstP0`S4PUaX9E2V!LPbtbg;RMgth zE&029zSjL*wRz~e^ZlsVvfnwkh3O?YHWahyGI@NJe9Gpu+#dAz?c(BX$*gxj@ zDl7bbv4~l`J7to$P!z*-;B9tK@LT2bqCNNXX6)XLvv*yVKF3hqn8c8~TT zRgFF%ZP)lyxlj0`qvw+y4S8_C7e6EOt0>B^Ck=Yp1VZa0YTO}-P|;%KGr@5;4E zo1+A87#L?7J{Tp1dt|_~bKNQsO1sC`1JoSy5fu#a|4ulFC8r`OD8d7u#`xmn_S)7# z(35~S9L19p-VHX~7Z*#JlxE}c#oB#y{i^SW5qk(fHhn3;{ zU*vtic;^{+bMs>vwo;6nY^l|Ao=Y(!dB3x`@F1Es4|Sa+XVs@mG!mN7Y&a-)~V z(LOAtzzwmk<~oMm-e*2vbj9W1I^h5nody=l%_^bIJ0ULH#nZ|d{Hj2MQnul0H-)Z9 z323qWpc*aKsrc8;#$-`nzjeN)O8SMC!xlo>S!#&+XCym(8xxk-3qfp8S=v)vY+Nt* zEw3#n!2qcwnWJc;X!!`o?d>bE#5alDGY01@`WOWlO!!q^fg$ox2vwpoHIum-+iw!( zpmzEn;l!XzP07kgsbdN|m7uhK*kiPBbqTD=$TfqGW1? zXWT)q)`yS!yLMOf<)P)fAwy<=#o_7jFnd<%68&~+D)wBOcCMJuy6hjz#jv4qJcqb> zf&dtJOgw#rQSRw{cN(KXbL=l)EH`??GOsTiHhBFv(X;m8#n;x+nrb5Km-SP29>aPD zN82$FG+^k2{HUrn3R^NXCB1FWz9%KS;PI96P~uyGbrWps6nbQrR3>RJl3X^yQKuJ3 zl2fWNt)+vNl0uo%)nv%ZS(%+kpOvR!DZcjy9T7TS|5txyn={?uFEO#TZ{NY=9m+%B zyXFd0-&ObOH!tWQWJr3i1;dLB1z7(eu43Zv9lcwoB>K;*>J3;gTo7bXMx}c1^+od} zWLH*2>kHg2`i-_9E2p}hwhs8{4BDs=-&6n{KO9aGMIT2gy0&h9nh{pxi1WvCg@sh} z)1HSp7N!~UAgMlO62lO))+DbFoTejm2qbC(Nl`eju%VEi%5@6ub2guE<%9{nek-c8 zt*@W!*T+rU{0zCR9r*MDJ@;ZUGaPnlt@4h(ofX2BFCq_t=fy62Lm%n)vq0KJ9i6aB z=s%av&jBZ}VgpT0oj;#D+I=P!R$)^mfrEuLhZ#c*UeWNmsHwk`Fxp5+nDJ;&MMe%f zd;_sl($YH>8fxm6u6!v836J-ZagmV+@c%qOXIEix2AzyQ6z7$qx+ig+?n1r&c$4e) zp5pt+GNKq=u1SL0ot>RM#X`+Y4oh^%w{KVvzp6_#IQ+$a{rFLOq;6AJQbO0;-~YV? ze4rtx5+me-Tdep}U5XCeq)WMz3OK>(M!%+%@Do29+gX_a9JmpcwS12~b?E*$viGs_ z=s6%ByD0m(CJl5@w265rH9f%tO9Re$2g$z%RY$B?sG4r42V%R73|$4Hbk$PzM$cpN z(NB>j^BSru;!%II`YcIC>B7g!>72q!+RXc#fg8t_2QY9rxE(KE( zD;TO>M!wnLA0~qL6S@qL4p-%nD{tQ;h<;3KE2oDJUpH!@|~Dj@vmHtDa_idSJ-O$?@-uYAn#Y zdwNu=422{lB;GAGyGxx_{0NII5wtV>$8a`QvLKe*{1zBH*rm8?MSfPC{7>l@1Y+~HZJXVCR+$HIMF4_KgF?G49R@?@`9wUhIZugP;b2I zc+zTF5H>D^M6`VRP5Jct(UQRRPQlgKS8LYpg}QEpVpahYugV+0C&JW%6L?H8?P-F-u5n8lUBR+cNA*M*`w?3SSg$? zdd#Lyb3mur3`_WS$25!glz`b#j{U1rN4rvidpUQcNC3Qm=VSb0tDv9o-J}hl+GGyV zE(Lu`nSRye-gNnRo;U(sikz3Puj$rM`tKIcD&t2mT~T1~cG}80we7c*Y9f5)@b)G`n@p)mSoZQ6oYN z3JS)$yk;;|qoK}4cEELZb(PlDB^DGCQrI$RzQ=%2a`vu#^XuN7Bz)*cEbs`S6s1lg zyuiZ6wL4!N9!BHin=_A}%$Gz-UQ|<6WpzB-=5=~U@gX@`ML8D=B2%bZP(OqJ@-2O{ zpRDt6-zOQHkuPy{QdLP>GQ^|#`3*OR2HHQamv4D zZ0+nso}arlwzQBG88kZO4LR#JIK;sqpsz-~%4QWXYN+VNMp3P?7eVI%d}66O(RjcY5e#A^O}LyQ1GBTdROI zJ2VUoxHwfbwTbByr;X9PkJi?SskP7fPO$Z45!K6=a5ivfVlKFr=1N6dvhK0Y296Z2lTLP}qsG{2yL4V=!U ziUKRC&MrWqLalhjtA6Fo>#?c*ckQXbi zo^W3&_R{e15a{UW@Vf0#O0@}pm6xobcFy3mj>h|yy8igU`Nz!CbTnIpbyFlcc3w}n zo{&f7i8i!U=sp~$?o7evqw^kRc zLbtB}1dFDkIlGX8yj&*B+laX{c6ahbLu=`CpqN-!8ZR61aT|fX2Kvl*3vXKo_krY|AlU2AuW&#k@StMEEU6aV(H%^cq7&8$~jDnA)GWWZ-V>#< z0-i_eQfYyoMINtEsHv$Flatk!N~e76=WE3j718lo3}a6>2DCi+CDaw@^{3c5CQb*Q z0!m}`AKk&XG4b#;maKoHJ=E*BdO34hzLD4*ueaALaAc!TK*p>4{ac%tmkyJR%pmW@ zV})0^=1qQn{>dOs0-zES>gcXpLr_7;c=gD5To0+!e^=$XkglZj=U>y)BUe{fJBLwuz4D+N# z(wwR5sN6NkC@54M;YLP2*4Yek)dBD^0h2~MDIH4~{ES4|FgoTBr=iVsb25zavGa?}Yqr1ENTfl=)LEiY; z_UJ|*fsq8jZ9hN1=dr&76iRcHMR=;&VwgBIBBH>s%?Av!v)O$=c1EdC)fiwCSmOxb z>zJ6BK~&=5l%OEe#mg1a@6*1dzMU;)leE7)m}_+1M%VnRZG1gGK3%T0ae26qCgfYM zvd|YpV0!a+Q$|j%`x#gqmjw@gSND`4_V)I!){F}Gq%dfq!kJthEfIo$e3g0Gu{1|Hf z>yzkSuGa@1)<|4B7nFqi#thSk^ zClv`GeWjG$`*-tKwa1|@0Hy+Muo}c9BwzvD0nTy?p4q$cd`T($PmDStgM%`3xX3*U zBy4PK+O<|#K37L*g{o0tCz@{lOp%i0c>NklN#uc3-@pLvbhgsK_ToNYvr_*bVC#Q( z3BWcoHnum5&-I(%jZ1+?xmK0be*-J4>z4e%Qp;=!S_D^Aq@0$i11_*RLGii1-LGPE z+ffEr{%Y7p4Bnx&7w|Z+I&W1gR^)ZviXE>7H;~Ebx!#M^db?Ln`ylrM!}jiEt>+ZX za<1b_yVXKH6PVR-cr;={WK-+27=F(q(q^|^6V8gasmz4zW|8ByV`It%egH2M0j^>v zL`KSKnub$ctZ!_r0XlSl@2B4p(6;Do#-1*lH*QmRy`2*XIBs-pE$5fQLMkpUyw|T^ zhjZun{YBz-Tt*EH3_MtFBLRzWpw;{AYqk-2>q8Ex0#j)%6p|{v0G?0hEOXXojRGa5 zq~PJvNh7z0Gim7P26sB2z?s*_r75@sMf|Q=b?fbPY$%M4jd{KQnnj6-zCwfsOBxd& zA0E=^aYzit5i6TatHae%VlkYt28K-A1g_sYr5_bpa$qx*uIu5!9gaZ}uOxf}+tt;D zh=S7d@wFPO-EY=Eo0~*+p9Q_y!4UH_%boA9o#nFyi8cljSn3j9s};T5n=0k?I3WD{ z_itiKN*I_u%@#@dHo>9eSgzRM$Vflf#Lf@5?woeNF>z?+J5g9#mBX1p{hz^x z&hdJCz~zO_ysRPqIX&dFBUiQ08rZiq{QSgxe0=r4z7YnX;bA5DN5{m7+u429pmFr^ z$Ip)F?n6nR9ep-KxGb-efbPrxr-*x=--Zrzt>H>fVWRw9J5$~ zyOk9!RMh#z%z|H-n``afO$yuTPMyOYN-VPJd5B9$)V+BD`Ca>MuC`$FrzSbHBERT-BK)a>px*<3)nrEF?^;7H*wwj|c`HP1#xFd$yXZC5AzRUOm-_mIP&hckHw z8dd^gKy5vhkBclpR<~8T+bzyH0ZfS){Tj%jaD8TJef_MwIJ#&;4hvLJUd-6PTu;1Z zF@7e0)__izPeVg$bt_b`Y^KZb{OvV! zeS3AB07`sXZA?N!#GAb5=S+zR4YoF1l!VF01n>@^0;6D}%S7w&>r4mY^FRpNp?udB0@vuikB`r!YepvnN?RWoL-o5ZXh`Q+o_JDbX3S>+PiTn8(PGr%qCP4a zKQ6dMOxOY{88OV0W#40CaJ&?pG$!m<{U&TcG6jKBphARh_Bf2Dk&aKRox~8*rPt1< zqXrWV>cF3LVk{NBl9_yu!+9=PI5;9aR#)*v@Z|LB?Ycg^eCu?+qtZJtV7k^F_Pf=a z0~Z+%R;;r>j^y-m!BIR<83F+ivm9_|Z@1Wp1wpmcmyDpy@!5NAW^PU;EWA9X6%Zf{ za5dO@qn`-b3X~ToaG7Kdu7|OL!b}-%yWc?+f%jNBfscIu{X~X_*5cAIY!K;PyqHZZLpM zbM$JrU*Lv?hbOK)LkbDvci*F=q3PL)1#CGP5(K_qGdmBcaVS`hn1HhZ;vfxI587~b z%5`HhVq#F(+1cesg1}5Vx)6MMy!6)6(khv@0c1YKTSh66R@)8n@6C3O^qV)(4$G}b z5bahkHtL!iE2Uij+2A`>WD4pYUfFdv#UEQ7ep{9|48}Xw>g@^~g-r8D zQTJ0SnRNMZ&*jdKrAwf~WjSC0P+~;T{99mKO6yl<%i&>+T zYyvDS4Si6=#V}c&*Cph$c&q1K5@lYToSpRmmt*bt*b$T-P{y?M900B6p4OeRfp*QY zrU4FQR7dfD_=*1xLjSJ}$p8O<{}o@uhdy=ni0?s1_F8r<)tmExIY23K%whV9Qg1q$ zKT~K90};J1tf@Z;kBqblK1pm2Z+^$X&14f)`EAbUC6FDEXOo6np!+|q-+w-N?vA@8 zdgjYPl`Q@g3oB}`(K#>h>@6hn@d|)hDO?*Kz^gZMP zyu3l~R;yG!e49Q6IiF5sgMuu^Hu=$fHFx2;PF$LTn}sv z0ansO$%ht-tAn}sMu87_9Z!z}q-11hlb}Y&aM{kh1A0dzDLiRvN*(getDY7yBo7Vz z0s~#crKlb#6!{EJBy@Ci+B1M10>`bUUhV&>){qnA3cEis>5UagV_aWfQ&Lhw#KTd= zTwK1Z04w$m{cygHqgSWJqe7+Qc1`-B1DLWWCnv0eECKMZqVwk#qeoa?H>@85LiJZe zRwV{-Jy1U0+R;Q)KNtF&vu)GeiNa?c_uc##E6{O(XH1tIc88&``Ci(+prxf|W=3ab zW=`XE&ZioQClkQL!FjJyu1U1csNXnd*HKzpiU|v4ZEY>{_AQ4X%hBC&2T$e#xZl`l zYuP4X``d%7zEx6+Xld~+J^cTomkKf!0M>`Hv|mF%k1<*e>voafZ3hB0S!5()Ow;ZH z@I5pC^cyQsQ!kW$$lu!93O_$TS6u)+038^GY#B4aGt3h5ow3rjvMO170%klgt>@)SK*3_Ktb z`Aq-XCPCzp*XQyesyHWr_?hDQ`0%^9x?)jKBw*1AvK?Nwfv$L~u`806U z#DVaTN+35VdIV4!0pNV&`gB9eneh}<$FBDXZy9ZF7s0&116Ts<|?Q4INNcPzN~mj8)3v^7(5UZsJ8H%rJQGW&UR* z_3wz_bwz_UCx4Js!0S$**F2d^9MW)(qf$}GVzn_4S8=3X60Y59_WD`DfS*?-DS#Rl zTrzvS^VN37t#1q;xBk8zS!)K!eKE4)P*T< zxnIy4KCdEH(_8iX+6}F8SGwD(y7NOOyq+>)7&O$Ao@ra2A^fU&7w#cYz3X%(qvt;{ zt!!v7%JK@#vdN<$AxX-}(1oLuIk+!I+n>SG<91|k(I1cC+E>zQVDZ;6<#^<^8sqP>Fw2oNWcf+b`6w&exS|5@hF3LcN>*xtVsg z3H>6AFCi^W64*sh0Z$LJ$OK%rcShAFuZt8jgVl;hjjys{N;dQnjys+x#509_A3JMH zDX95&GJ5Aaenig!yfuf@;;Pf z8(3_9j5@7jC6qeJzkah7j1>$N@OtggDZaXoBjT`FyIPT3)&$dRc17=UvOm6|a+(xZGl;R~Vk4u;21!ZDPOmrGPQV|a8aav4grDx!TCWT_H7j(_zEPm~ z<9;S5$Fe>bWdAPo_;~l#SXYK7u)v(fP!1NN-<+jxV`qDdfsD-UbF{Y?ot0(RQ|r1t zLS1G$fZd>F{QxXv;E78U)$NZ_A#aR68JI9TI5=fX7yt6<1VZ6?P@9I-> z-(0W9j5-}J3jx7LDngzhd#uR1M*%4sO^XIP{Y{1D#-ATJX>9)V07Z1x@-6J23i|>< zTq6H;O+zZ|hxo6khgMpNbEs;2<2{YEiHfrFyVH#2)!FcOx915?e|w#me6o4tcPW(m zY{kQMKF5GvP%;~_2K);e0RfcfILL2@5?JBN4AI096j6f~^e&VO-<(nE?U!QHIYjzD z3pA{)t_CG0Dx(sgv)^KPRm)W0!g3TTiH{Dn0Gp;jMFufE!D~qw^Bh#HV4w(Bx8g`n zE-v~=3I_5lt6ni~X`PE2VcXuZkQaO11CqG$9-|11Tci(A36%y1p;&T`5!RKc$BV&q(Y#kz<^|dzl(|M7+rVLs+xdaxyuYPzeKS3Vi%^*M$cz^8K%4QQfcLUf$WL#VyUu;p5hzKo`MQsi6IIrg!_q?>qkUn(L`N zZ-)vjhqCFiy)8%?8K{IMnx-lR&+gy9{RO9M-%uU)c}r+MWA3Nn%(1pRn(5ET)0lUc zhmrta?dB1{$8!?u5tk4*1a{Do91$PT@eS`EORWU`&^`c@hCX@)Sf~G^4dmZ3_djKu ziurSYg_)TdB`+@_uzLpw2Uk72LDxp%b9)X&z%|r!PD1W~u41>+-bUY2$)--P;a&{z zy`ikO#2z>!Rc)8V&x9YiBzg2LwAA^5!GPowuo(6}++B^=*=hk0LIZrZ(QWsGF|eJK zOVyvP9dh3THcqQCh@qij_|5)Ig*f2$|JCg#Yz;;!x#2^6J|D=Z!NAwZDy3=ALu3miaUo9rX-mc$as zg;qB<-UkIiP>I-KK{W`!xeXK&6kJ_fGu8%j;>-)g7Fd{=5YUey_;--zcfEb4tRJA4 zUqJ-&$fz(nG4~vW3f~=Y=r_6aDWeA5pGpI+j`8z45}b>G8nZEHI{YB?tUv`}M-(Vsw(u(M+YWPu52 z^hgs46b^X2u`DoYc3OKglr2OO6&3ZI0RyLqRxu0lAFVPr*E~#2Xh0xHEfoAm-t*Cx zEGqJ`0(6QNd%?wOE;03+O5%$kj zrynoVV0d-`fxhF8TKOM66bJ^IyFHAYscE@_i<}J?H<(Z34H3h$JK>i4+(f7j+dfIN5xTwzl9Q zR*Q|*Kh6&h?0U{X&(ph;)h=4`EY;Gf9dDpi#$7!(b3@E?5c3>(A^54_CS_;G1B>uWQPC$a90~9^o&F4BfdiLV4}mU{vIoK!d<7lc zd`~S30kitN&vU;Ja29t!kQcTNng=U1QGnOWF2u-)3f4R%$ac0e4}fzTr?qO>Ee-W8 zPxVbYpqF|lf0C8DhlhuEP^Boj#siD7v*(5V)_#U{Hjh(<5D2;%Iw2 z0!R?hMnufS1GLM*N(Ti{LtZDVP$1`w06Vb9?;i;de^2}02O6C>p8bL6?OoOJ$iM8hfd;ZX@s_kSLa+q$fIWC}bu|DU!s%9~qvpKNbB&oS zRvG}l!dQt44e%mNzzQbhw$n~u2OTkJ!1oSoXlNMc>IVVF^GAs2=+FHfryy)t&2(%p zt-S|31}(Jn)iSm(T6SoR=d`kA(YtLu1vvv5$J6yb(5WG%s2G39Ub_n9t=C2z4=~>J zHvPe(*?d<2c6N+l7du|C|DRb;-8M?xKrGRF(A_~JB0_a1lcEDM> z4Jmp(29Ok1&qGpu15~W&J0X=kZhPHlq+Tzy# z^PLb@*||_>zLXgZpx795)+*)mcr;~-7%{|GzSIItHbsHe@Yi?GO*-AtDMsSJ^}PI7 zi=W18Y>kW$BU8}#{&N1wuO3_nESj)1>H-y1U?9NG&3SAg^S=|aoM_+akf@WDl|0m4 zXDaXz3l5N)jAm9c!+6w?JlxpLdAAxfTA;SgtXwLHW@*Q0qn@ebs}Og`_due)`DkFi z@=)UIY8yum$yF_7^;pbIyB)u?*xrAtn#N!KzqQC|($>yHTh+lKBA@p>_tjmczZwTE zbQwIhp{a(%L7*_cdwOgmyk2*GZnqoGj986R=}G+HGE4VZY0!~>H7PXC%Ly@PaqGOw zZ0Gn9g(3XaHxmEqZapFYuIcf#JIL~M!LcJvzQdD+$k;xEitBzYlMy#ms9Lv7rqTt#vPL(`dGpgu&^6@`vdK~=uvm5LuJNAy9vjG1bseMg* z%s@dX&knMbA;QGO z!yS8*%!;QafeY1BAw4Bm^L2>n?MGGIRQXAKu2gw;2{B2gnyK2_?|ysUE5y1R=6xi(uO?q$&n=CEX;rlLZUm1X#5I~!PddoZg{YFOj{!NI}wG4fB;F=_ei1MA2Y14QdADO(7 z4T#8z301d)FU9#(_-6yJhE=Fn?L;k*!ic0tYY46P6q3r*^ zKT<@5l6^~yl9KE~vKDFVG-5DHNK*D)_C1$S#AIK`zEpOyl#o3;k$qodEcffYuFv;A z?(h9QuK(bB9Q}|n4(B=NdwIQ{&&TuaH_!b&zmj=r@3^?QVrk*uZ`-6ds86QlEdMx5 zYu5glOX!WqMgN>_^x+M6Io3IRjW_YE#eya5+~;;TSv^@rbCa>vBpAD{&M3 zCo-ROm9i6s#pzxAV(Tl?(jM&XaWts#Q#bhsGnz-0nRhY3wyXGT$zZ4&>jUTm;55t_ zyYJ%n8#W6HG*{J!Ox{brBZG>fu1=Os>IG9?HHY@%%Z`T@QzjXs?=-E)YRsNbuH^kO zHMn8uY%ccx{ri+%RKC%{L(>$zAJBihvzmGzjjjQNmAcrU_et!V3BP@UJN-ruqwQR1 zAd5d;J+_WyueVdvfXOHq`PhjqbvYvbgO)@_oR36IMKaE&I7A?C0x zO8{Xh;J$Yr3UT~?EL%{BoNBr8beq|nRgOmHm%hQO$Wl_&t!ky!uj%;tZnx4Qo(QG^ zeCE8ITsMGP^M>6v`ky|lze*4Gx{9MMy{XoepS z=ytj2MEiM$!p2k7X2f{ysk5r=lGZfzn zTQWeY+BoWRE=#@yed{xC<>Y6GuHremjxZv{~ic258mk5y18M5oCDI-UQD8Xn}K3cR~;5SyWVHi=CNYKl9ER z8;}$LWjF}uV{P#_C4NKwhxkH;MMa?_MScU?{mz<$aw+PIiD^37;29%+y)jhlm`8vr z!-d?|(P6lsAV~qU1!xL=UJvNaR=YLPAXyyB8ya$eWaSIY1IqEa;2wMiOgHWMz!&uf zK*5!`SO%>U=n`2&3f=);8cAVSYo0Y@(+2x^{xLKQaxis|W*U6Xz>?HZ3h}uDff)iTXBe zigey5YraqXon2iG0C)s8G&FR&cUzRevh`8`fP={`^MSL+UuCFWvYpd?Xq_XawGOPK z4X_ksf`Ii(DYk50rCZnh!V_)4AeZLBzf1F$TZhQ1pscL?eD#-tkB`sTu)}E799-ZD zK(3yQREPu7MVhKXK|@0`ROP0hbsAhMkZ;b4h%m5?C8kCg5#I({kwDNQkD&g;Ok@rXZGD1H4J3^xps#2h zf`jT!b9WAl`C?OA0sH#%FxU9yYn~g=6o)wM04@*kSi!C{MoKP42Aqo=0kb~ z#E^m|1%Udql$4bD4$FqH^~+`nf-hOI*{hE*ds@6vTIqYCcTD+XrQKje)1Ns5t9m>< zJq97S1Hj=V+zi+0O~1NrgHGEAstfu%Q>FYjZk$3`JD9%R7Q$g{ z;;%sF?4R7CoyBddojzQ?TK@Z%dI~~U!q9?DK&mq$%_u8VayU)W!D3+qJSxB~1-(_E za|FPYsskAZ>D3YZXmPNN)baUgMMXu#J4J}oiN?^?A96Itz?uRNTVXJG@95j!bV3iH z8_8}X14Lj15jU_7rsQ>KaI*)>zz3e3ocsVrD>!yF&_2SxMpZN*rxj7>QA1yFIK$jr zLGar(WN?4q**F;rk1!DMF(BiKWG(ge^>ob4=E+@fPG4-+$B#@f!i4|Ksv{;XwEy#6 zsbm)neN;#}hlulhg>8%32eV4BBj_6=DXpil=>*&nVS@D5c~<)!sgh1v7dGF30Jd26 zQ~v0`U;XbJM{BBA=M3j;PR`KCW*}Q_-(XpilM1#wGfyUdHwYH|;MIfVtVW&^N>F%I zNDUcY@D)veuj^GERMX%}O7TpTF%6J&Q?9gXtMhbN1ufB8r0 zFOS0w($5OEx81Boi{;G)tz# z9hckNzA9=SUTkjr3Spj$W$iyg?lf$smHOYQH&%M8PG4Zz-X4%}ong5(!8>RE)6c5k z`mXex{%}j)BfF!nWz?KJd<|3WWn9ybrK|L+DOz;C%y;iQ?r5CnGw^~R5Odh&mSk}> z`t^na#UZ(KnV!--)*t=KRAt!3pF73!_`!kTiE4In3he^QA<@6bTwYH8bK%c4DHZ~Ex=1cF8s}dCzJ!&_X z^RoS|3znoNg`z-@ILiW7#AP-WW##;>F5$OA<9M`I*`t5fV|x!(sAxWjRo~k+FG^a| zq~W=rHtstvXIrYvyJ=?A*l#OuyPQ~Z?bj-Y#OA=!;+_G#?m2#XhE*Io!(td5(w8G1 zjO8BvzWQYciVq$zqnH-jqbN?!B^51w`6^T)_RA?gQ=W&1hafREq>K7dAjfqCb8IYb zxzzYezBi7(g%|CX^{SC&9#6dh1OGdw}T&d+(TQ;>Ak?J z#?l5yeZAYceK-3w9jhR${Mk%~jRSHi;d1_%m^K5OwQh>Yd2;(1pXAF*#l7rO_FrVI z>i^~x$CkTZtFnvRGjV=Dq$OZV6=5HR)$;ku50W^J`Zq3(LquiVk1lVUoAV-JsT>Uj z-O0`0+CULK`Pa8rE4+(=!%%BwwjF-oef5=UTa*RA|H%^ZB~y8{lGvU5=8|up4DWs2;Ol@CpAF zGX`x5Ea>A+hYMdmQmBha`AsE=M>}gxCvy zSXuD|tvtzDgU`mh-J+Yl9g#Yg=r7XfBd8;ovRd+G{!;V&{cJSW_2c!nF)7@Vn|8-f-QbaZM{ z4?|K_Vz@;_bgZ2q2?tszRrI{zrB&{SEPuvEux1f<&+s_(Ee!YErf!7O&MBy-UMJYF zM5Z+weSb1|f0dRl0{7zQtdfd?G+p3XeyQL?hu<_pRs&S(c_9tmKSi^M#SrE_Y07Ak ztQgXmL6>|b4?LX0bLGhPkyW{{mNNCQokQs?H@A|G&cn^7u}Gx1Ad>?U#MCLv|n;81)4IQ1aPA4w7z0ka0ecy1?7%RB?L zXO!a)S{Q@Fue`leA7=1svsl!48)eTa!n7c9MQ}h@=;^}d;@2Sgp8^khYKNW7>fD}DS;xP(D2v>B!Pq2Ye4-f+5! z!xdcu8OpmhjrlvkuGZ~ch1uW|k$TqN{wVU0R6lzmcHjv7fak`B;9DU9vTe#G-R;bu z!@+X?<8g~vRx0SI;h$dDJD4ts>wRw+l{r_t3wASE3*-%O`S<7*fTO;f z^%8n5h)e?H@pF%D(TN&152Ve4tr)R85YW6_Rom(6Q{S#|`JV3svq}*2{xeQwcYM53 zwU>v!)0plcH9f_{9o!4+-yfkgs2`o5IUG1m-a!F*+xIC>RUksEabYAzlJvQ#d!$0RxE zNUW_nD~S&BTN3I1)Xe)PaY4NCb*=}e0W9tD2XDPLFjQ`oqz6zHJF@)Aw z?Enr@vR7PpHcwD4CAv5sr=(mmCvd`h-%C2xWxaHGli%9Xf+XOOTLhjRY1y(R1qDxo zxX}Fl`%zR%N(vWz3Aa?Z`?JS}8X^;S?^3XcJPiP000dm+M}U1HOh>9EadknPZiYF$U}8Y4!9KLxb$gybvgdl7@+=i5Q!@8MUTX~ z9XhX|Mqd#c%VsmR{ zuys{`SVuC}_fim|qZJkw{m9gO-7{^a%x+1388--801YIFklu(z*y1RNAK)6zKb`;m z+ZW8cUtr?OI68jpl@`)`qn(lGKr`fRicaZ~9T8I$w#X(1r;Dldb-x z^-wWFL5UfpeC3&x#GSkeUS}u-9^x;L<>c@s59(}2CSP5-8`^x_5^pPn<=2Cz<`(8v zxx>qi=)C)effsBz&%ym50=5D1&X5b(p882n6Fr;aFxU<3y}?kJxZF;JVV< zQ+Y}%UF?&wrXJbt!yLEN)6>$p1qC(DI-23(fhLxi4z0l*ek*Z9m|HSgo&4Ssv+ zM1cx+^fsu}r#;Cv-+)%~WT5ymB&eX#UInW1+?6XQ?B=>Vb`Ec(S50Be)2xICMJ#)% zKmoaQ?OJrHosCVwyj}iLJTgIzhf$yi!mNrFu?iAUpU5|=mE_Zp&d@%I0-5`|v1@T} zDM&q_S7fb&BRVmCct8%ZA3o?;eSig>$V?|Q0ksjb;CayZGHx9dl6Q3E>CT>hLtt`A zz60?%E#5Pb@Kn>&3jiGfl|TOh6R(*MxtL5X*-Y1!p+t?$l|HP;I5;hxS?SO(FD*g3 zflx9sv^(`w--hxh+k5x(S&w_AOWusye+f|kGussZv&c+zcPq4;mr;Qvy{o-`c-X+~ zLyYWVW_rY%Vm4o2Ux;^~2w@XuNxEb*nbCoKWjoi+T#XeA&(B{H=I-|VmQEi3{=J%p z#;+Ak!_qXT$N&&NK7;lEP+0$@rSY@Y>5PzbemN`QOeHHT zTm0>&?eQ=Dg3L1vERUaKTVthO!KlMcG*W+DAv&GkRE16~AY>u@0_U~5G*#@_YCyts zd;4COrde&>NkwPb7Qg$oxt@5!mwK^!e4zsJ%dcA0Z?yGf;uM+I$y{u zZWZm82)R_I=`f?wXk@(tAqZ9-kn3h54dNy2UgPoBMH7SbEKhPBV8wvU*=qISJ`Kzq zWE8@~_9VCV`vjIfly)f&Ul^d0o>JYfuCP{iGcz*-y;kKn3nXspV7~#ITva0alNAA! zXIM_7yTV!2)jOD^7mg9umWDZ-Lf#b>NS@_jW}c-zO6TPjf8G9Jv5w41rWK*TPQ~D6 zei&osfg|>##=8Y^NICbLj^+2UDr|J@J@^ZfVlcjb0rLoMfL~FOARH_Kj>y%@L17?F zJoZ-oH=Nahk!C-*EcX)GQ($I|0~7%&vyge`QTU9JnPS-T!ror-*|Te)0|5p&G&BTf zp-_XoM*t3wu>AXXs$Hc}UnOXK8Jg)~wN_R;-g4T=mT0V+5nuiM!GMwzsCR><%Rerk zpr)3~NSJL}vx^nA4%-MhAu;df$};iCI(?I){Z!ggeJ8HuX@BPo&*Py_FUf1XNlHO> zfiqM5VUmCQ_6=y9bL>RWmm^}D=FN6^lg8=TObhx7n;+Ibkn$=&8_xIu{<$c`TEhauXh9n#6G{t^Ex zi|ymVp9va*$EG<16Fte%?7UIRv3_09Pief3qPfoPnx6hr36`^!e~#m({ddE3QwJ!sG;VHYQuo#L@|LHS zBEO1TlCOJa%rLG5LWbYSFDW%yjyeA64@cCgf2oa)d&)Vzy}glS81O-ZbFM%XL@VFD zd;9tGd~ISrZ#QUNDW{=JDO7}4-du?;+}%cA%aNu)RIoA2|6k<#x0Xb2-^Jo`W>Z9h zdn3cN22N{>oIdc5F08r`E6yScJ*@+17G!$G`R>Mo4ooSNK7mrW)dRDT5~vd|uUhn? z#{y-PPxtQ5=_h9G@l8G1eOW}?oL|e!{$aqYd)69d6L85TPX$UbXDnuC&90l9P%WJq zDtjy{-1eWsQLsDUo|g2F5l0-x4j-m{>Qpo-O2Yn$_4RIx`JYc9f;+G^7$f(OtTAsy~RW@q}hO z_M}ybs2@f+(`xZT;TiD|Myism39dvPBH7MBuOYX7M7@l)bB0aM^_Z)fHbuDQ}m8wdybr%FMZ_G&Mm!j^#s#rA%fpko*PmszTasFLu-&(%Dj+{9>7>Fg{jGYR^1<&*13o>n;_! zSp_8n>6}*vdxzWx&pij#GP=OF0yOQHqb{uJ_Y=P87mX<1DI;GFQz0&jNe2;W%{sdT z91dhb;UZWGJsbJxrHke8I?G=XKyezEZTp=U+uk_=o{-NYPTb)E_WEL|XaV0@I;eH) z!G+4VZ?y<yo(>rZ&#;B||i2 z9tSw*DnOl5arn5oY>#0h_HD!LHs{WSFiTP9RY;Ic7_#z5J?J9SoPXf_9_u0HDdl26 zKDcZT_>-!Ib^86=dL_N<>E6jpI7=s zRp7}Su>TAPt@%#tiW{@+UcCekg*?OI0=Ge3k+_8O-0Oib7HGd4mb!mphO>`+LCE6uY5K`SgWkc6A(d+Zl`p@k7|EweD0 z34C%_dEVQ%dgeLhZbXr(?@r{41EunP*Wy=ze}HNO1r|`j3Xy%(_(u)NlhZ$rc(D(1 zU7Qj&eKgz=D?L<6G?QHau8DjDE*>}7r*HS|N?7$&$n+MAz7?%Sv}j6Uuv*pLnAg6e z<&-V>8q~AQjIZBUoc#JVJKt>kTID9mSfrgLZS~V*ZSN}se01{I5!^KD_o|X>&p&z7R&Z@lbGc={-MmbaVtXseEN? zwL?E4GLjV8+TCb4cW%5<<_QUQJ{FkW`++z?N7lshG9bwaBXy-wk%k5h$*a1SmOuU% z%^*m9F!4Xpkplf<$9wZGh!0qeJx?fqJ}y}Y<-cRqe}N-wK}|M31tpCY>hko*-rv7P z13PtmnE6bSj%3+dcylk*5DywVSCiz7xHL4ve$9Hd&s;^TO8M2?zb&y%{9#-_ZkWe$ z5zQ8UL1lt&#{~8cyiz75ujd zC1C_+!7E{2jg2acrN`lvu)i6S4?{MMy)5go82^)AVlEf!CwFVS%ZSnZaBzxtY*5CM z6Ep#vrTr1o7V5!aM9Jrs(RT*^CjwMD>XDh?X(<)>?p z1-b?-oLrPDC0Vj{FN}jPYGW-~S(?#OOG zP1Y1`2z}|dNjtsbF*nzeM@0rp9+q39$x8eibHn84l&BiKNQn_}?i4616C1OdZ$*R| zR#!Q1(<=b>2PjL<-zW<|Z(Ws}i-1cn6=8x^B4%yA3H>%;XSuz$BUwoe4vERu%^f4W z>#}PcjpXUFZNyfo%eQZ(y>VDR5PSUneduqBRXF~|pDW-v)q+pKL{iC?`oTO{ZpMG3 zB>VrMBz1t2+^U&7(WG{+FyvBDr~XpwCQQ|ztHYvqFjZ9V-o>C$1kwSc?v}i<{%Jo+ z$83+C0vTG*7yR0=!UWmjpVfR>?f4jj51;Ad(HlaRd_kRiaa$KZA9ZM$;ukg9$`Q4J zfCX?4$7>Bf8||B6;kXBc1v|DrZS2-=hvKNP7jfIYSFyi!&wIjTXIc1gYp#cNx#}h( zXT#OT-!1PD>gZm;yYo^0{tlupdnNLrG$red*HnntwG6BHgoLOP6OEnQZ;u|pxha9; z^-3%`)|Zi;D~Ejs&$@ObfpzWG$bNK;%~I0HCKUb8XJ%|FAEg!QW{}9V8&-A{=~{ae zx7S_h@wtZ&(-+_-?_hP=l&A@Zx}$gYvaM6v1cazUtE1SP*n}mz2g)oTy)aPKdzbYK zeYUg_`P42lyxb@NeqULToma4@L?a$z}Fl|hpPFQGf z*3#cJ&6X85(P5b-;Qa;$bA^qrigF0L#AAj>-n^F;J>IfItH#Xi3q@e%n%}{r* z@9R6av*0A zn7o8#J85Ep37mMD6e~+v;^GlcXj|uk>NhqiBLlVQUr}Fe3g^WLW1c<8_;pBHe_Y$< V>)J(c_=9(-y9)Q^b7hTQ{U6UQIJy7; literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/edit-matrix.png b/doc/en/qalculate_kde/edit-matrix.png new file mode 100644 index 0000000000000000000000000000000000000000..a8277f52b198a204a839518a3586fc2a858ba43e GIT binary patch literal 28460 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 literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/edit-unit.png b/doc/en/qalculate_kde/edit-unit.png new file mode 100644 index 0000000000000000000000000000000000000000..823d771ff3b7927dab99ac70be14df8bcce96502 GIT binary patch literal 34657 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 WqN=ekUr)l1LuyC&XQ-UH{Qm&oQFxI6 literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/edit-variable.png b/doc/en/qalculate_kde/edit-variable.png new file mode 100644 index 0000000000000000000000000000000000000000..80fbe5af5ff099aebf00074ee5b40eb5e9349664 GIT binary patch literal 25241 zcmbTd1z40_+ct`c(n^Yi2uOFgl7dJNNVlYPr%HEA*U&>rH%Lo&cXtfk>^0B(ef!(* z{{MF$|FNIr@EN^jX6}2fYh7nu2FS@spra6?AR!^4OMVnpKtg(u1%BZ?dkU@uiPCr= zA-zG86#by&l(akN=!P?PbpanRmt@M67e;;l9P6?0=Fc>xA?k%sFWN~JAh0LsEszg# znc7$%vNRtz_&a^0e)H_v!%#(E7N*oc|LVkHCZ*H7-20Ji)rV#JtK<$K0hV09Q$GcuWyeO*SYJH*3p%E z!x5W;@hd{LEEaWN-^kR6x9~lG%S%?)^JqB>S^A)}Ba@ru;jQqZ*6?`Q+8kfh{-+j? zFER?}Cil6)lc>;0)%3fsh0?)4g;{#-JH(f&Xkg*@{LOv5A99YAWHIoO`sUt_WMN#W zTV>BQ;~X_tG{grBN=O~3xzUKy8FP`aFF$R7+qsI$w>DYWo69oA|W**G$!1CywoOj5l2D z(2g=gbI6gn6m7X(XkuhD?iQ<}lTg|lR%TR(Ztbad_CsG9((H+niaN9I# zh)UU5jg{VI-UhMpG>ud**ot1W8ytir*5BG{+QxfKhtkh*MXB}GrrX*S2lnOK&~|8O z7XKpmQp)I*$4 zebUg0uQXYD&b?J)bolI9@l7pmyW8ieqb3ojCkti^Kh#pzOux7~nrwF!eE4i_J*Xya zxw|8+uWdwvacsD5)O0wK)qC`$D0Hu2^NzM);jSgqd11FThK~%lu(Mcb33s?+xnw_@ z)i;Ne-!*KkJV!aDQfOb3NUIETzAQES%ciXgH>2Dc5B_Zshe2sL|1Rb=9xAaSlNCRl zo-Ayjm1|d5gRt^l*6|~X+V#Yq&0~(o_!r?)Ic{qaM23wB^kvrYWU?o6#MF|<6VmcL&n^u zqqEKUyE8HE4#{Hu@x`yB<3`c0Li6xFdfB>IC80N$6REq}MZGTH(*r}>VQzCI;-wxj zb_!fFOwK>y+d{#l1a^7lw6s4Ryotpel(W2Rb?r_{tOdeHvV6-g<&2^Yg)_T z=8l_~XsF=|FgHkCbJ$ZX6bK*$9*YF+V6-sgt zGKNR9F>z8&5@xYEf9J!H&}%gg11mnu`MFr{@hUZItBXE3NM}v+B;T*+`M*}ot>2!HTL(EHXED=FmNW&n zJ>Whb3R+LCYp|c46?7oJ_sMV6#O&?-9HOx6ZQS!{Wr5}XruBN@krjgrKKjfVjQ}HI z-Li^*GCXL!fqSHKQe!^!Lbi~%$Ja>s!Q`R&r=WAZ9Y%&m^n@A1=$G0dM|OCqYxz$$ z>tCzK(8&~!McvM9fubK%(Vd~6y&>zT|hawEd~cCddBk_%o@wnEc_fmCjxq-c5%4 zx9u^T_r;JyyCL}dTzonSU#v~Y&f?4;C?OSG%&P`zNSY%2AAB6_OS|e~zC)?Y z3l30diGmy7Z)deqPN+bp>^X72`_*}eJJP*q*I_O$J`k8kGQZs-;-%tZ=S40j6bQ42 zeOkK2l1TP_FJ$!Y%;FFBQh&$Z@)_=)w+ydVfUz{Hr%DoWuu5MSz6bk&Y=a$6VFq2G zc&mQ$_9QO8PM7VAa+BSFC@rrtFJD(L0aX_Mxas~U>sR=emWt|_^yA~_Rn+EYmimcG zTP*2AgDit_I?5jQ1Ym<1?SBsO)TP^7iDx*9?QAzoAbTLEed_Twpt|?fqkjK@WJjsf zO~BYR>UjgojA)6wMh)N27arJ?6_@cGX8{!rqH^v{c5e;`qr1UufP0BT+Avt8o35vB z@C;n~n(8vv9q-_CfUJD9&0aAyu%qJof~g?(!xJx)EUB%H_&PW=+L>HAl`ZwlYoGH5 z_m@>GNdd(0eCT{uJC_O0{KR^G`QGoUJH(H4mc)b;`kYtP&3)c=8C;6X`QaB-e-7c7 zmLN#D7mJ$sO`|5kRS!W9T2nx;3MT!jpttZjdtmnCdTKXm=;5yNZ}@#YLm+^Y;1w#t02;u|i!MjQg#M^MSNRqhBtz(ck{Q6$i)H$A*?4`Web)_Rl(>cr;!h zvnd~}9vyVC!xV$2^slk-b_WhaE$C-szK=H-esR?|H*-W*ju{_M)fU^>e40R8`%ne4 z?L-*1qOG@Lb%-iHWID8&9CD2N4C><5`Um1y< zF+8)V1M4%?()s@VyT@bJ>n?7Dwt};LCE6BpI?RK$CIaFom{hk{G{?6DV`)E8o;b%F z6KnK!X0_jS_5I$bF=2PuE8e#xS?Qbz7ASS~z3;(kBXYD0le-S}#Fv%B87@1PM?FH_ z`4GZ~Pi;(Hcs@=&dyzJNm6I5sGq>*^U7w^d*+Wg|Ar`~rak&vob>}~}@vSl}Z_k{i zy{f%PqD9fH=1aZh0Z!n%%TJ>_O^5r849|=3zu^4(JRyoX`gTHXD`c>8LoA z?i1qYv65a{VM44FmhxjGSVUh8^;H?2W`YY8X@Gw?)QF^ns8I>>%u+eEpqkXmY%mZz zc0^9zWUid#2~Upk)E`_-d}36teX65?Yh%@c_@F0Gyszq@P@9Wgh#ljp9Q)Nvp+6=( zRu{rAH50Fgb3O|+-g2OZlpzaq9 z8H#JYx^@Xqbik%Mc)D)8T7F(-OUwBxN9`1Dcg!;Jf#X1VC7`_CT3fp!s^|F>_k@`Y zbUxzAg4WlSpgX&UoEK$WB%OUt&LwBQj2}|ugw;iK)fZ;H)H9fI)c3MrHy5Vr`56a| zRT+6<8ob+m>fkZR0GEIho>O?K1rn=Pc>RiK+R&*54H5tY;{!qtR9&*z`?W{yVFlc z;`O(uu03&25#DF7GylPH1)`Du=}M^DZilz15&hufc?GRjl^^$;sy}~9iDQwRJme(U zr>r^s-ka8J1}3Ey&Pk4mQ92 zZ-f~=pQwIUvf&p|Mkb~BjCVZ}8zS&4GapljOr3t>MZ#Q|39dhJ!Wny?D#s*;>bIXH zAXmvgyd5&L<6LX93SFQsr1y6aAuPG;0IOw2@rSr;Uj;26>&+Y>${V z!}WPrVz~C#7NV@q%!2!ea0@eDHyIJgZqJi2cBJ@{HGOdvVNlV`!ymWk$5=HoN?YHU zv?y*NYlbS}M)vR1Tvj7lWE0*8fBGn*y<&{ieGV)czm?u{VjBRP3F=dEU6G=|}K zVqvI-;$CD-$Y@WLXSUX0$cwu%+#1{LVh7s+9nDV~%8&uMO>%z?9on`)rgO6xJt-MC z4Z?KSJDo4Og@mi@+UoM}+so{4CJ7AkI4ksw-K}WL<0!BlNlFcf4{aY@Z8T)+Qn+f7 zPu#iikyUv9Ei&xJZhBkHx`IE)f*WTkdmHpF6M9}O2=-UymX6;o$KGM%c6_Sdvzg}+Es`f6hduPqb;?=ombH5nHNYZkVKp(L%m6D9jJ zG$>uKE-z}gwys;$EGRN#2-G=NAM_K2^`)6;awUv8Zp<&L5%C_senLxB6W4wF?GcY1 z3t^%7(qP_~^3WniYYQC$}d0ak)MhzEt>KBcAdstP69OJRar1Fcqzd3&TvZLn;}mOB!ki zuH)NA>ViH){tifqZ7B5c#zC!4YzWaCZV8BoeoP46<0duGFVp3s9VlZe`Cl#^7?-;! zL9*2SsbDA(?bEA&6C~GRc?9O>MkF5l80?n2og7JnytV1ZX7_Cm^h{pC)s3W{GsVHtc`%BFIL5b*96-+D@qnTPwAXUuBnx_Uy>_>J*@`b0Ssja2r ziuLVQQECXL2X(^BnYLx_7GB-mrtpqG4vqA2hgkR1S9DDjCM?uy!rQ#ZP7>N$*KhH@ zUzGEkx^gq`lO|8$B!@tK#zSV~hl?A>?(!z@SOwW56N{k}wBCSmpdUAKksz<}-u-YN zQF~Olbu=v~$8MNn1k)_ZKPhb^nUQ+$_w0J*7hB`pP8pjA+>gy%Wvt_9Ew_n=EPk73 zdjVgSi}!Ei)r`&r`O>=_(#`f`beY48uE*0Troz3aYVGrAoi}X-kGqK%x>|oLxUz|5PwY=UmnJ9Qb%3-O)X3=rb zq(Jxg0@a^|tF()Yz^OomP6=Xo--WuVxox$ozzc)1UfjtYp`Z~7c@ih9VB?4(2abQ$ zVDtJh*JLnQ%)vjK6%VIX@+lO${W;$^5;s|n@xA2^)#Rih2aisRPzN`A6Dx8|gjmc{ zbb6B}hN|eH_mhd0DEuAO=udrrmu{Id26Gw<)<@0Lza%PlSH3L&_x9zwE( z*_u)obWb#Hx*OjzsNGd%YG~cB;#dmK2hJ}&IH7Ui`vf85YWjXjy0^B;G+|XZK_r%; zfA6DoRen-B^=^HU^JPcvEtiR=>?bRCrukPR&8B%L`8igWqrTsSsMt!?i91B?bb><$ zoV%_^=5GyW4^*(rp2PNfjVuKNXnJptgPUM-^D7HDynEfx-PBJjRPTyP%g#AX=O~Ma zF4xak&)OJPB20tg3_D;`@JGCY3P-h{f-FU9nkZ+nhC|WOM^vqKg|^$V53g~LY*%Vh zQUVqCve_}Z4dqPrNgCI?>Y6;e51wz0?sHBTO^)?liK6Aw-t(krl;Z*hND`D!pZK)DA__ljbnn=H2xe%|tOgq6o` zowmQiYtZ;4jpJPDf5%)Ze0Ah z(p`0N{?X8{Avbc6n2e30vdt*cO9q}tT=yN+YRLJw5s`(g+g>Z+-sPp#bD~mXe)hNL z>mmPO;3bwQUSqM_cSPG7{$5l_xOA}dBgzXtFKgq1*Sc^MJt-7vePj~cKgB&;vwFSI zB^6X<8g;qynXCPqHd5wB3tPSn>+cY{hL%Juxe3%l<)z&#mx1Ul9~l znkKmM#`|rTx~TZ%p1dH>LwIOZJ?Ukb!dXtkb?pJ%>h&Y(gxf-s&nx}SfN3L{ zQ0#7-*{Wd{SdhR3BR5v5AwIxN{xr`a7iI+2)T@Qd9{G6TtbR?mw`(u_fO^8HB`5cO zxEPsbbuG=-p>wQ>$0b&+MI+c61k)p7d=WNPG#su?RDbxAfzekg($ z6YV6;SsxXJjW^>q1W^S-$?it`XZH5igFZ04;S;PpsdTWZP+jQm9*`!dI(>J^v$blJ zHPXA_#WC`9d273Ee)Cg3yxs7Kowpog-}qD}4Q7yYC*!b;epDu99QDVcgOjE*8K$Pg zpUtY+H6Yy@p8Ac*!Pc&Ms0_npLJizqcw)pyWjFdu)h&V}TX}Z1m9x6*2`ULD^)|%!c%31MmNEMo-QB@WEdr1W`JT=}d^`->g3Q)S{rk}qcscn$bpMTD1|8S_zWucKk4rkER+U`6f%>lby#)3Mq zL$6W%z#kCD+Fk>+%ZefD>6R3+rHckFzm5}E@xY(Zkrj=c=Y)k`*2bSRB!;%%=eJf^ zq`~jP#QnrG*kr2wU{HJbpDc$ryi}OScZxV6EM&MfJbOw#q#;m=Q^xm0TOp@PII|}h z#>8_h0v;BP=TN;{S0S;3KAc}njvDVbR#6BwbrT6KSIv@U<;t&GZigN>=7w3cm>p?*t^5Pi6#z?`#v&*x!V zoa3ux{vD{iU9M>f=MYbtJ*(jC4{`m9)nT|36CVZGAG__TVI=2FWWI<~T?b+i!A)IUY_XWfn}^_@fK?}G2vo;9P- z8S9du&CU5Kr~HZozr)SuUQR=qL&t7l{_4SI0z3JvVnfmSh531vyhR`eIM+#+n8 zL+_7v@3)Qa4>jADrEZ2-)afQjFR_;`Kg$npCtKwady8AT*}WF~(AW1+1$jpHIDoKk zs5Ojj!y|8)3^rmku(Y}42c>@56ns%RTe8GQb{C2BBqRfs(Y|LhJy7ULa#;zN)75Sb ztJL&B^V|f{KWp);>Gm)gYx&^w#_o@Oj61=sHl~d$X`#4Ug_^DBW0f{!Alk6RXy5ly z%^kApVT3Ou%#2&pIcg5vJ-~%p}r@(LxIuLFnsy_ z{qlGNo0OD^lz@yjt=!;vR8e+mXQwAj=Q#)oy1H&R@J{8^a56D@`9P=+GXc!rJx4Zm zJ%nq1F~xO1uksYdnoCJlK>^37lhiXQI2f(*ay?O@=WKT>s`A^6&DJpG+1`wVj0{HE z*S=Ef<9@z_!*O*>>&qiUkGo5wpFe*RFzX<(8TGHG-rrE+Gig!0d-qgGNJz_Ni}KjU z^=wynI8#zoT>Rzh*FC=IufNpV(WqBh#E@v9XAK!&T&#p`O_q=s6%|$2)C}dTFzM;( zP1e{_oiBI_?eFhb*VVCEExun~UIq}oKUa6W7OSn+9uyYV+1csmd3T(OM!@`sUlRfu z9vLwi&3&=8wS_m*+S(cr7|5zk;C_2L;qB+Qvbrj&qw~gWqNsve+m2fX0#Pp3`Yb1h z6&e}}mie$5ne@x48~CvM!6Hq*q~zp0NIss3FB*$wP+oy}#s_&E9I?FZuXxL{>D{S~ z>h(@6Wkv(zGT)sMSsnSMny%nJzm&zb9p>fY8WI|!(lc)nDq&th?p4chi*sk zD+(&AGSe~I{4KB^EKF4fT`%X|&o$q^eQRZBmkG&NE>NoobUt2JZIhLff^C1skNK_B z{1A^pO;k_stxAyw83l#6R)Y(?o35DI^~`*EWu?aLlGT2DRQKirjwGEbnCv+3+(|nQ zgX9x%TfNcm3|+fEXrf|Z=yRhl(r!v=YZDzW*0yByJl%$XwcMN>xEYqw zQyW7h5M zKu?eUT6c_e5_iPA&k0ro0_SnA`!Lwi-Sxrof#-eV`Mm2u5>lo4RLl1Vk9r%T!P=KN z?5W+s!#o#PR}DxWdaQ(SnUA}7MN-mhHzvs>^Db>}e(Ve-R&8{v>HD?|IteJA(L6;z zA5{FK+w+Bm5>DLZfz8mHl;O>xj2i2er!!TSRS8@UyI*E!XD3SyQ74Kt$!TZ;61gnZ zLWUA$u#|Bbb!!8fbr!eB@+<2(P)J0s}*Lj+* zxV~jL>r>x>(EW|=!-o%zN3zk8z@cA09uPv-0UthEs26QzmtI7!nNSmnh_>w z8fv{e$?_C~$e2WY#F*V~do*AqM|P&bRazQtuGYRRPWeXQ{qcGq!#w^19$6dlN2zQ~ zc&TBJ(_X~{*yEBoQe512keWY7L22pgdj8!D8B=-csgD<-tc;^s>Y zKmDRt6}GWqRaI4WJD+ouj$=;m9_RZu&HlAFt~r8S;%`?M89BL^`}G-%-KJcSwTtuB z{=k6U19s3+=Uop3LW%jr&CTf_A!D!)V4|T>u(L-yF1W|W#St8PVcws6-b;Y>0nY*Y zq~PYMi|wq#-n8}2g>~J|P_4aLK5BlThA~ax+w;h_g?ZxJg!BMxDz&*D)dm+1i7*mM z@M(YkykGB6?g@Uy1~X5dt8+9OFHi-`=$DrE=BJmJYPA(vhIk09)ZRZ~Er2RTXQMxv z9>7ITss~|%mgNxnD|TZn%X;`z{f^)dIV0)RC@u{tEczXYvmZotg7mdNsSDKJWy2|+L?}@+aR1Xq zkP$!tIvvuWX~p_=8VpuyvnGW{|K$(BvFFd8E!J$Ltbnfmj*hMeRv!R^;f-)v%>FGm z8L0+`2nJJ&VVcJnyS-Krp47kl+0K96OHkJ%LC+WFRmZe7Asc1&HS9)!()v8cPLE;W zBr}u37lT+Tnb*Ex{mGLj5y{ElI2u6bR6gf#b}IE;{DDlr&lUqB7I^|L3!;^dkVnB? z>tKN%KY0?rF$1%OZ?*cO>rejHr7Ti(kzGD`-$sEdOp@sRsn|ibd}+ zKBLAPCZ;e@GN7uNL^_0(zMn+5rT#Lx=vi1uMF0S}|2pN^`36@uoj*v7TJ;}quTEbH zxUe%dUMy?ohhcdtM}jvff3C@aQlqr`VH#Z=E;-iG3g2vX0nR1tPxue9`8Hj?{HHm$ zP7@s*PiD_%J-~Y)c?7I(R4~YfOb3%da?_tH)K5NGo)+LoSv@=GqyX=6NanLIIQc>6 zePI>}sGc_#hc5-?e}3V2r}Czb&25$N58$z{$|o~@<4mFPOukV1xyf)F?7B5+xmf=) z@EnOYCXRyUIoU2AwryYlc1M&4-HwHd*ywvNKeV-`RCiiQ$!GHJN|2bQJqmMJ;EHf$ zBolfc? z#c$6+02>;dT$mMPWMsU!9LxTk$ov%ZRrl?=kX+%Z$!so(ik|1AH)$pJ#FpxS$N8J8 zOfB&x%M46tyLXX?VZ4{eNrc}QNZWHI-`LvN_y^TVj;5zN>93pF)l|{huJ@MJ%u%+R zy_8!>`a-Livn;gm9P&cDap=P{dB*Har3m~#ugm5QwuajQotaG1j=$hog4n$#A|f&# zOe6DpD%8QXV6g$1i`(sKEN-aE{KOg^S8tDs%8c?au+pM6N@w0{dwZ?k0a5Yrt9-+h z?<>p8PPeC?!%%0ey%zQ3Z6R$k@|9oC9#P+~+%DHP_^&>CsmC@w;O?@a{4Uu_{?eh{(?eA-5*r@u41P zd&UQa}ow^jH~-k38?W!T}wu{B}LQOktK_>4NTbLZ((_+6u?cxj36S z_}ky5dskn@(CvA6hjMqhjV6=C-*@*&p55f--`~1nESCF3T1hXv;44C9p7&&KZnsXS zsUy8zIt%lpafCcRT~XR^);DbH@9${mJw2Z+9L(y53hCak&3byuVi57S4CHv|p6&AN zURb!+L`80mHM&dmr|{@|+^;k?aPIuJ?Q|qSd&;O)>kFmUsC7&J6kBWyALa{3hs5A}*L)kCcsYXqgoT&J{8q8#5ySyhzb6p3Mk8=Qu;(&E#&x zL(FT}*4+F+c0jHE=7=scJM*xZvZo;XVBtQ)dFp&#yTAT2Xmc)y2?GP8{MomzreE~> zphVVLCyKQ*91jFR2TY&XF&TLm>=@gmy_C7SwI%7|k^mvTI@$B{@_N*#?yWYKUheeY zw>TCPz4`$eR79yEXZ?8Qm1O-XF z(vgrt#Pv(=($cc=4g~o5k)ENUl_sRb#F(TwY;UB#I^X>gR7(@6_ri1X_tMS6cfYOk zMUirgv4noj+U0`-?PV_%G1ka=PO$C9@h*&q4a>$@kvu# z@|4HrgqcCjTWxg7;N+Etre+VWECfXq{Hpl3S5RXcH6_HK+>TXj!w(D#TyC0{k zEG=2?FG?~B)J`n{&+d~Xr`-;R1RqgkLPyjq&D*yWg+|i#a};)FO4kI+&7Cok07s%+ zUP68)q^pou@{Ka0pn(2Y(>2CGXrd0pFEp7qmOxe>2L%O14ySz<0|ryhbq~DLNZBh@ zflyG^0iX4lN@?C_ZQuKl?Mw!N5GhVE!3 zQrB$Rgd6_jji$b?sLrnb{&#?o0Qz*;JCf0BnBwe$KS;&ekecfTeXtz_qJf$YPpRipEr&KDNnJA(GOEXl^;tX;*93XR;)6g z|GJtr^Pl^J5jC>C;xMHT!z4Cf@q{z)VAS_$p7=R`Gm_&q9$ z&BLRy+;q;@WJG(V@w!$$dS|xgQ@p*?R#sm9QTL~|IRt(u37j{fRLP1}^=LsNqNBfi z4CJ}{HT4!-*Q{n!9q!ro(Gn{?gHMzLs*&P$bZ@<*+%Z=anEQj3m2K+u79+*|Yw%o; z=)VE{2{_4XibE+1#zEN*u^gvQ+fswj77*AWMry}xdp2QHurhFc>*#6p54se=ER2Ji zNd5r@DoM#`Q3MQ4gDRqo_@|<2Z3ZNw-y<&aR+x+g4scpRCBn9EQDMsix(kh@fLTMb z^bm+OS!kOR`W?PXE^3XyR#I|YN(90&{sXQ768@2Y9l>3A=dvLB=6`xw-QttqgJO`9 zy;~ohEAqvH26mAzEz5RBhu7Ly+-{@-z6o?w4hr!xX(3IRaLn$Gy>=4 zGlZ80oq+j!Um{m5_x*^hP?k!u*2UEolv>JAh3c-Q(qgXL3scZPEDW>1zkk;A{?>f1 zc8p&e0_jf`8UP9+(9aKMICj$k;&cy}yu`l&69p+N+k1kk_A* znmle@#DfXsr^fu7m?4mO9$Q2MYl`FiMp#l(($?9@=6+?TT<}GgF*ZE>Jz%0+Q)N`( zUe-YOIN6^|1UxA!F3t(R>isi$2yJq7eM5uE@t}>gA7oZfog6qH;3i$i?qn^J0 z)NkEKpJEvecg72CEVpI#+5>TcEdrg``9!=t*XYg%Y@zD06L7P$Z=GYrzy_oUd;;yo z>7e1fcLc1|zdIIxf2U%N6-WtMH@KX>rKJswj>b7I2mf=}oooiIo1r@e_(Qs_zDvOT z06!8ZRdctzBMU7Y9A+VmXM3o{`?;_Ebf!+*r554XDP;h5I|B^DE#KwE`LKbbovPO2~sB zFnnNE;W29b1%)B`>C+0RB0czWJEYWI_}Mk&>NPQr7*I9v&5W>80F{6~WB#E^brS{^ z)Z6+MjERMZ|Jj`?n<_KHw6?a!!NEaN+BQ7_Bpo<&voMv+F;hAsMWtdu_2->d&=E=y zcwI=7KzBq@$-Wa1m~)e5B`1HRqN0+&rm3m<4dVfR4vZG8y8h+Sn)yOwGN6(PIZUdh z-fKOvBPIG0IAZCFIWh>He|LMWvh)jutXsiQn~mLkk~zg?o5of_t;s{+p#C^iEWSj) z^Ccl+Hz<`{?IuC6eyeM1@>Ld^brXvGmw=8GX*C2UCaSM-3D4pJPpbfUFa61uo}}}w zm_os^vG_psu~Jbg9>EU}e}8GrG=R(kRfu>}u-5H!b8~uH|0B#Bu$KGtOCKCBF6!{} z^K)A*B3+*!NaT+V=P6PJvC7NK_a^Z~0il_clq84a1EA#>!N}B9Jg9*nQM;vJ^SE5Yw=K?LPft%z;<5F; zy*^igH46Ll3Y0TN(nXFe-z^e?_?LoG%$s3n5krvekXV=w><}TM(+W5xB;*;1>K<4 zb`|MXri=I?>In1{UECb|opELSk6D_`&&l?KX+KK=!p zh{$s^G=u%wn%+2;j5a6W5|Hum#Dm8sxk5;Vq_N=2NVkmhjUh83c748 zs3~MhfD(+89v&_pt@Tj$W1^sd^VRq};k*r7HqMjrDp~_<6zCXUkV`TV-!E+q2aVU& z;FnZkD!;pmt+T6ZnZ+Ehmh&1e@KnW>mGKzVD_0Av=1aLbZ*FcTE6ngCA|lp<5D!~s zHo*w4?P_U*JDaMqBn3N6MM>#nGLj7k_G?sRWD95*H6FLT4<0<=KcBS))VBxH*dXj5 z*|nhf(lHrI{rKtAqbZ}*7}X+Rl(`-Eajk_~G853x`+0j?!I#B?Y=Dy1pRKlDKL>mI zhMGE8V+T;S(3`JmSUz9_n}JF8x2K1kmp1{v(%HlO8*5D3MM@ZFd#;Y_(NnZV;3I*zyIB;nXfk%gm(Mzg`S?wlxAc3!Ka;tCZSZ1D;j{8oEte= zSwofI)G0X*_aha03o1Z@Sv@HJ( z)@)yU3G%V)VKBF=t(=qXF;r60RMrU~5&jU%;*3?KY(rtRzy<{tD5U4g;6mn^wFKyt z(U;wQeGD8O;bbC{)z%q(*!56qL=SpFEJ-G?AX%c0B! zXoih|_ezB`=z_q)z`y`lIS|Z_ znVFgOfXa)LZ!?u(|1g0`^y$kN0#eT#>pUuB2n2q1#@Qs~dB-0na7GaFnk(C4u9pAs z&m*_H%Z)6HDuJD3Rzs8wiLgpF3vg(q<8A74)RgORG_?VA_U&8`c;0!zU{21?@l{8#17>pKVA!Otdq2(Vr1zgWE!R=_&+64dyFal8O z0@X6W>X!qXGRZ2JM;s64`!Xe?{DXrjI5~d-|Ngh#mI9yv%6fXVjVU=PE`fsXS617j zGyt?!%Z*iw72s({Mnrr72b;%npXhsg zLqsHrIP+&@r_~4v0)WMs0w>`$v%sEo0_!~mxMIK#Lv0GM)e*MvHc+i!UE_XL88!Ta zy6^ArZdGe+C<#M+ffJdqH&eB;v!lKoo?YnR3_=oTcsu^qL~&}Ls5{jGjo802bpFjZ z-qmbqPetMlySHf`Y})aXxSz;#ew%K)fUi8bSdEh11n(3R4h#!30(1euyI*xRx2-vl zverI6zDJn+e*lG$0;FzhzJU+y7rnJB zu2_j#1CYxgPHVcqwGI3qjh`6}FpmcvU>-;7xEwevvG=4QQ@YL%^ zzDjX|Uy*b%NQ)F)--=Bfg8-}qfD-~&z?Wvi(MY5}0`M5Jc;LhJn%1+KNzw;3TUR{sIw$Y7%t@6nb$oB5Q4D z$1W@6beP8D8?Z&Ov%4#8YD$}ulCu8T=I+Kh=;&X-K2oU8#aA_5YXl5paK+olCmlu$ z$hO_ybWE(4OI}+_K*NrJ?K+z6M!z8_k<6?tgdP4bm}H-5PH`}qtK|T=o1@+2!MT$` zjq=p%LCAXlxjsTpR+GbEIgdNAGxDmGhV>T#z8HWs1R!2`OiVjS1ml@?AL`s%c|oZW zssX`8K+0reYs=$y!92i!94vMT+AlDz(L#xMgh6@;vYFkPsxScSzrIW?3j~4R9Ib>2 zMaIXQXf;}|bYz{C@2Xmgi$4Y3U>zXYTW03)-@lmwCFsbN&j3C*C*qFdLAyX8o8KGY zsQv}T)pvY*d&^_B_+1m9Fa{ydtR<8T6%-&bKOP~M0_1Z5haJFMp>F~R{rW(Q>J#t* zkrLvR{&D#WvcUg}5|);h*iA?M5eL}$$ROzGKbiKW*IRXf1(sSZ2|s-F=s7w%LTs$3 z|Bd{`WCo7W%U7=?{V<3LSPlGZ8Ufpbs+N5PEI*-VYJ?F%4iMx7EEQnJY{r9cfYLKf z5wcyE23+cUYU%>9Cxu2zBet+oUQGTttHGhrF5~@_XA}MD79V^9@Fq~ixt!nB;D~D~ zmyw_^PT>MmYij>AAmKAY&`R0wkCwC@l+rOta(W8=Z$;z3OUVC|KWVd3z%)mf$blXGI0+9)I?mFN_O zx2G$1fX2sa@qL7x0pMnJ_18V-6*}P!LF&C@*+0fKL;^B~avL)hd1s~T{Lh$xZu(|w z7*iPR!gdRx>V?0^jRjK1!8U0iQ{+oPW4NAMkN}hcaY~+M9cNzx$4XvK%CaA+M=op( zj389EN(*G!G{MqxlnfeWwWosl z7qYi+p>3C7A78xqA)b*pSOSg|NSH|T^71%iRUk2=qe^b>?g3$8OpZ5DYj(nGA%(MF z#hVVO^77fPQfnS#(J8|z0=) z>O4=RTG-q)2B9}Ct|w5Mh^(Hn{~kyqC(v=>r>BLZF5VY(xmL1y*%Vo0`6|apJxn0a zHsAnWl@^#rIKBpb^es6#{QR5>gv21K36F^Q0fVh;MOIaDfeaCWow16Ln193PxW1@f zz#EN$W(6T~IzY(+^(qVyxCU_posIeOt_YsC3_uj*TWBA+88$QX;2Zh)wZM2H7&5Ic|Y-=2)b zsDS|#h)srye_dgVKvn{)n%fx-$3k(c-2 zfg_`$`g-;NZb(MGdjSp^i0{B1>TC^XAqrLj11+x4FNUEc06fYLNFbgV;KvW|tD!RD0 z7XqcmHUGc@z!sX3!Q*;X;G6&~E_`I#eYpD01pK*l>oY6kb53AN@HUq zyTxprh#!V3!#OZsB4T3!`xlVIc>;l4g2opIY;qtG5g9Td#kM=+496we|1}XYnuiUB z9{`HxFIAT=$GL%80MN4tB50sOKpAP~sU&H8-g1DZ#m&R>f`H&Jh~F5xQw3aqfddc+ zXaYj^gO+~@kau?yRhS@;HW$`>gJP^v+@>;Q!;zg6osb|^s8+E{>w0x!0&2k*Fo2VVeP0^wWB&`<<`h%)d) z`QBxE?I^rzD9}TUNr1i%<{$KrAL_RGzW^7y*KOKeC5ibQGC>(rP*5OF zRcTpSp^F)CDD=Swg8(NoHrB|tZa1LJ39iR!KKWivjS#>*3rK-V;_V=iHQCy#EI1OCnyo+_tC(1YE3SWIuq|2h$@YU072>UxZfYzs^Wa2Mu`z-|GK5d!*vCVa$9;t0$NyUoGo zWdcC$C^2-Sag0E1p6ty`5Fvh359W<-z%j+!djymL<{?5dgUHnOlDq}8S^2+b0VF~X zd)WrCh>6j^2L+*S45a1&cgt`elPoZ?Nrwe6|JCtA>3rwUUWDN_w^3EQFpb7B4Kzdu?7Zr$G37Xk>5)!sD6OKfb!>D(ps zV<$kS+Hz0r8RU*@#X;ClX&bQchQg8Pe3A%I%cV2G32Zhtl&^x4Fo zU{awJ3}Rkp>t#`};}YiP1^f+E-C0huT_?4NX7ot-9w8MxO&$C%1wj`>%oNGUgpTn; zAbnI}xw+I}mOxTRC#{Cd_Hgk-&`~za?Q%;?ORvgLO2p6(@N+7`jEFm6x4kN9?}Tno zuz^jK)u9YV2gO^#;2YRubWkxGbq9sur{axRq323N%)F6aWxxU^3dMPjr**q}6fLm;jDnyM9Y@@*h zp=GEcp*Z+wGoT0)d+625{R`ErhO4dhf!X=N$%z}B1_T!Zt+C&I@pxSb#_NzV zh?qS$r4hUnjBjw;tUlx6;Q?~@x8;H$m@P168W*HV4k1< za&_Ge0YR%r(7Djvg?@lQ)U?7rw|eVjCJAZ-~1=G z{4kib4csUzs7>(@LNPF}#=)Du*^L(n^Bh}O#t5rCl8 zP}|n|2XL=GAk{xgNxfxbi?VFI>~Kqp@oTVtC!5lXm=6N`1_sTfQ~2WnW10*Gp`vuQ zOma8SB>yu|(*x}!dGVqd5R<=u|Gp6rNY=b>YPiM-T2{M9x+9jxX&*e%Yesr2CMGH` zM?UjzE8f#{p1kyqBmtHu{fMBI@40 z>%Y8RnyW$UY2nndUKlvuC1(R=?E2NQzmCl|Nx=3gAZ!pG4``ECst+CSYuIuY-6LW< zRnYYXFITZaJsM{Tb`T&Y2+#L5&1b74o^t2r!hT?k?ezq%5$I2rn_vT>2S|q>XxX&5 zBG%R=gOZ??sGQs{AuUd5dy0Mh=x_COWpmRXK$1Qf*lPLi)%}!RiD)y;T!4jz1t2pq z7|DX~*B$5$LB#-Fi5%?=#Y5_A`;qmd$Q#Qbv^#x)|Z*wpm={sOV`T%IaV!a2| zGn6AsTA*2n2V4Xd(|fGjv(xQo!LRZCmzRxbi?0hZA9rm;u@i0{b_j%XaB~v?toDkD z!L?Xu3>h4h1H96-@b2Wq4xkpUQGe2qTJn|5lq-EqOw>mT0x&}ZB8c>pGihmQ7*Q>t ztzp2w@9Ils))kH^QMwr@gN9wSN@WNrF%H-V^O#blN zNXk+}0hn?faV+}bV40K))ySBce|JC9QVnKdHycL-fFKHVIC|CC17P*~2LudFt1^?V zR@AylUA&Hs2G&FfkdtN&T2oQ)KF&pHzB2=Ay7Bf*{foN#g#AbFdil-s=x6c|1oT70 z6U3VMKY`@VDA!#!Ao69NrG`dQM8YpJLU)O0Lkv%z9ED*ih>LeT0c75+{F{_irt<0T z62{``Z$)8$i|)VGa_;F;;O|g7t81xgBGe|z{OUSLHH7~rN}9>qy#eZoT}(0n%nbFX zWr`xcMo!_aHx`tQn&yS@v!Pe)SD~Y|qe%-^m;D*rs4s=LV=Nr-4mU@|Gk6i7M)~QZ z3gfNDL^_smc|ST5yOeZv^v6P=^;=)#joMRtV=-KBuZn0i+A3ybih@TX^WH?0k^*09 z_mq+n%u(}-&`Ea9&Jun7`jwfD%_}R55=8hcKt%)QWt!nqs1w`_M$wG6!Tix%Su-Ok zFy`3|q8h7%c>zF;o&lo#3=>nr*f>|&LqDTZ{wPlX)V`R7MG!!od0hg&HHc-tS8`>re!ETLxuvf?1I9c# z2M2`x0AwuS3)^GpR78&z6%-a%RumJLx+3h)x*|tu+`uLHUC+=E$q(R|z+BVz z@5aT&Z65f)`nnEis{j6fTau9?D$p##V0|5?^fab!%>^3tqL!>=m0!4$^_W|4iS8Ex# zNbIP@ur9!jFMWNq&{U}TtfS7vaajE*^0`WV2I$H)&vBua%dhU5Iyq5AC}=tO(h7-* zwF37evM#7u4TFOhX*ktxnVF^7_yTc~2U+=HnIq-t)2D+&L*==#sCl5_VK|%s@v5q- z>dyZDm21~dgNX?(gcM?OL2yf8M%>LmY&XaKGQNkuUQ=D|Jn>>@+Yqw0--~S@09^>5 z$;`-rxUp*b9(F0%z8wP2F2Eo*76)iRX;gsxYT?sab?BSQ+Wg$yWPmf9K)p1xvm<-( z;K8@IBIIyIL0dbfeHw{<^Ck!o9|UEU%@_@M!Mmk42Om5`tMGc23H*=Fz_i{=c~cXg z^I$R8TTurTH2+Buu^!s;bhC)ad`|&}3e@*}2B_bWFJGPmNsmodmUS%fNE$-amfDEEGweR}1d zE0@T~$$8KYP@lumXhqmx5P^OH!BL2dYTxB$ZvAJ4gyA3)A0ePCHoX-%5rST;rtt|0 zIs>CH*s5sOmkndbcp?c|g<*ipNTjxQOMgE-@W5ukAPmp{QOA=f(i{s7b-3XA`B?ljVU1RI6FJv0{lCifQKL54e}^3 zaE6SGj2-an33J_7CU_%+GB&0Q;8eEvjX@MWCN>r|lPKp%C<`Qm-?5`Oy4FAm_e#{Z>m@6&n*qOn0;^0G_msI6IEP|~ z)p|#(-}skf-D|*O;V6i)VcG{d-U+>S z(&0An*q4Q_T=}Rn#OEvRwfd~YrdwVc53ZZS=5SqLvI}!7%tuVmbj%B|`tB}q(fI1% z(uZggjxuxfy`}Is3=IvpAa@{`G@GE!Z3SswQ?0BR1ATqLEbVr$Bx?xLe(UN|FCGOS zA-vuEx*6PGjh4`}e$_vbJz+e}R_`9$vi* zGbqm}02D;M5ypnfhdqF-6q+@Xz`#w=q&R3HCqP~M0A5$==6c>LH8@^ z`3c*667aKY9B;Z7R}_$*b|yx~2>v#1!?OsYmIQr(m>%&W{5}PBPY~KAxR94X&bU~n zh}F;jXj6ChDmCw;$_pUnH>3}NKS3Olxz5E^AAE+U*9p;mQzT%QUs{?4v?S^b@1#3& za?hO&)V8>}xvBZXa*ZmeVXmg2s7M~hW2&pG3t)5utE5n~`O~n(HCqPbY7eO2;@Ct(PzHtdJ<^(7r?6o*oNKVCE4>?`2k6@gz@?la9`b4YF6fY z*v!n#?~E{~kO~?u;u#cNvba_5s$@5qhl*kll1H}ZLPnRY&dAc*8U~JTBXPfxh+?NP zg^P9Cx#- zn+ckOqlF<&iwoQhzP-{Bm^uQ{qGWKh%I(h!$Yq#AnH2Zk;)Uf6u}YNmR8mnvwFqTo zW=3WR7?odE`M})D#hk=V9J0DVOG`vF`L-~>a#J`P0!?)1f^ zIM_(Gd53SKYEsv>v0d+P1_53|AV??}E>n1XS`47ZuX}ARCalU79%1V{T%uCR-X z>rbDsgEm?YBUZ+>ei4up{gy1t3PihM4el7=T}itS6Vm2c+nZ}wL`CVqaf=tWLd~t| z>MZrefQ(9%<2U|1fZhVEiY8vhzp`bs{j2#A>;u}Cu42JG%%nJQgpX-yC%2bJ8ez`F z%*yH%X42H&KC-7rYq;8*24`F&4@$h^g2%#7N>EL7eGFmoVpWIduew^*7JLcohvzJY;`p*rK+rqsm%Mky~rkUOSk ztgWo-TUwNsennt>*-6+TSX?xJ*zuFKOKax`Eu5q#(58rf*T%}2iI)@Rk~C_f zG3*LI|5+m1S%HyHY6xULhnUl<6cqptz+m)XSDae)8E*yJ6}$631y%-2X_CRgDu04pBb89VAGCnu*lj0}QT z1^vH-~W`U-cOo+0b7g~#2EDOfNAp|7@yO-s0vnU zcCHEbuPXpZn2qdVDLd-e`0aC4O9>6Q4FvkWdlzE8@^7A4NS2=uC#JfTIQ~M%NckrU_aE~0i zx1zJNAgB6!{eH9a@*i4(x8rd?OhD#Z-QI46#%E@08v&}78B{)Z7CN?*KJR0~4?#?q z*U->-6edTSb@EXyyfJL*jXAZ5-fSS+h~ZVZL3b81HiZsjnd;p!3nPCb!Csr|B|!is z@07s6KX({efki-6->34 z_?Kbl^k=*;MMt6p-82GoqoY1yC-s>ADrof>_#xTOJu;F=&AZ1`?&017rk~5Qd#XwMb~y1?3VdPPMr4JPmA=_@U<(1TCV zhhT1bQX;y!qZZNXlIm`GxU*d+#O6$)bnx_Q#yzU6ZkbF!814dPWU8_RgwdwOn@|z*!My6pZE19$dX&Y2D-8-W0 zx_0yG)%Ok0gYKBx*jz6zdumPJ^kg^+&GgYdo3%SVO*=DgCEKv>_Zm1F=Bpn9oD0h2 zSfi76%vKz`xoUHz@as1A77^v;D-%n7Oj{m5S2q?z{0Y7#9^TRC{F@j~OnPHYd_9^0 zMH<-jl%LVaKPwo@iGFw4vPEqXHMCo|i(tS{{zNlJF>c;hdyizKxpq&}e#ljT_RVVv z+=|DOJ71#=1d+(x;{5UPb168Vjk)uOD@SxGxA#5fW(FCP`5q#&He|=WjpsVfvPy)r z1?@L>r|`X(yvZ)^#f?IdDaMVdC(A^DP}Km}_q;X~4yb&mV)Yhfb^b)#=Q#C(k6p*s zw-gM69m%Q<2L&3Cc4HdocQpHv!S}0}i{wn^eVvDw5T%Y0icOW9>Yi5@%+bQO-|$10Aw9fncYr)Lbo)A2ns84F02umU;f7=0Z7xcJ#em2S;F zRwkDv?4IIg z74XJ27g~J(4vL(-|Bkz?`nQK$ic_xG2^NM)7mQAz1-&@k1zuWI>IqfFZ+M3hJ zg>ML?1|B`viG3$6c@lGWiSV~e+6H6@z0;<*RN-?1 zstH-_g8G=g(=r$MW>;qSMAAD>;KJU;nj|H7YnETo=P^y$kq64q)dOhTBR?l{O|kgDcaso^#{D;30$%J`D!`w1Qhw8VmUr z9|92^YIskD7EmWHV^v^(qoOm_bBm=AyoR+50|R=5wP{u0P^UWL_*$AG9{k_wt6l+( ztFqGkpj@c@Wh_~iHvB@7+h#Gy@*`lJ-{#2&t&5x&XERmP8BUTOa7--G$OnfSaKDY3v=`B%Z?6Q|k&t zdKXl8cazoLVXRb-sOb6AQh?2PZ?9Mc=zlUgO2E1+=O3j#Ka0)9eOoiG8EvdCaQ35N zd~V-gRKHHq)s-k@yLLg7W%}rF?qgfLn3E_V))nFk$|S((*wzA$fB`{&gVsWgp(rmq zy+e2Wd;Q<=!^bQz7CE>wW3EXVz$ECyQb22-aSSvSjGPlbiQ2n**O`8%pfOnwIu1O_0w(r#+dG@px{29_4VfcQ#5$A=fZ^x+B)q zFqscwJSIs-N!i#CVn()Kvi74WP+GcXb-+5ZaBo4tWwr}fP+;@iwmzAx117H1U5~Ob zKFKkKYn@66#BnL&X9PHoR$l2%vGLxuT3(hOUmpF~!@!**aM_gi`0*BQUK~HMW!VmD zQn3>5Q?L^7DhqrogXm$ESxF$k?IGV(;<$23UsEGC2pjUO_XR>W4Gjz?ha4oQVt1)n z*$y5RvT7s8w*6&yYFDn6Q8Ft2wRRuURIE`~VUhgB^+-4NNsJD`Ft}7xi+xWeakA#~ zn~y5fR%fy@dfl|NN}V2*nB-8oUFFK6|B8NBmt8>FH=miNaJN$<^J7<6Mc$gI-Rm{w ztjGJMVuh^TuhP=qi5=o*r?j-#6*}BDz4R0vjB9_0#l*~q*OtVcOAwpz%1qOKdY!B9 z{6D~D-ngfSBPPZU<9L;W@01p94sgmbQwxibktz>Vl86CoqOv$86H|^|#~-V)jI2s^ z6@LD%U-WhK#>O%iPirN=mrXuNPd{6EHt6L;3v=@qfT)gDFZV9oU}EBNbDbvzu`R@E zqvYR+P78l&S^n}KF_d5<$+ic+NIwcbP|3b$w9ow;$eGkG3^XQ6*vN0( z0_{6{@#`3}x2%s6oeU-yTd)oJzs#cl4|x8sUlsG;Jf@BKl+YDq>&s7X|8kiFkX6W- zknB|a;fk-#(SHUXoL?(-lHXU?2+_TFo+^@%m1s>-sD@G0UeUMhi!MTON!NEPh ze-Aja;WwOugYyDMPFh0KGj(&y!(ix$_SfDB^+FWt&eNw@NiG@HNqSz7Vns^5?X>!y zfeHh7jZQqWM-ge8xR93{k8qw%e_((24z9%PHWts>*%1$q%5ms?ZGpxyV`t_3w6STB zKjYkAJnu_X)V=T92wLl>lK1HXpS0XE7(L9t^^0PF2($cJpIBA6)GCYUpSP~POqi~6 zq3FGFf)p_=X4VSYJU@(u*DfF8=xZ9OTnwC5A5rS|GX23 z^Q$s@25CH54J97G?PhAYUHv~d$g~ns(0*%yP$3#1Y6>G|TlS&T zDK^0UH9TEATFLg$Wx}F3Kw6ga+8Xm&`R2jD3BRkig&EX3->nRADYMbJ8GvNsd!Ic{ z5qp`Z&x>SYze=VeNE4{xlSS&dDe7L`gWQLO>kx#z%l@5~O`G_Pb=x|qKZScN8C2R;K(v1R@wR#A&rGuRz<3Y(@BN-* z7mqEb&-p$Rsce=PjcnJ^A7z#7DbKP@ey&fMZ0z^ZhU4Fre`^Vo51O~WrQ0x0Dw(*P z@RYPXZF+Uf?x$gcs-O?4y7bw=LN`@N+5Y@bWot^Iy8>!OaiYrZe7_lAIW1>=XcTr1 zi1lc0pT3(@X;(bX{%0#TqpJ7mNR#ypfm)pRoqo0O{*9$s=K0mTo(Fob6d1~s! z^@@AsY@8h4BW{bBC!GGG-bsxaTPwXHcU(B;}`K>jHMLm&O>n!RXYP#G^&QybvKcnm#WAgYpd}PSs17F$|_egYJ9CLZc zsf#h|=cJtlAuX!1ICI17Sx+A~v|0RQLc8=LZEje0Nmbn%my9;Ppq7bKO2I2ew)NXf5A za}sw4e;UfK&s&`xNB@=%{PE|BnUlsuN3f1m!wLN+MV7c;RAmu0D;a0Yj+psAMA%VV zpR3f&@Ja*~O7M-}kr{-W16L}J|K?Snq~Sl#Cu?xG)?V^r!ppGXp2+#hwaS*vRhWoE z78j)xLYMGkw(}D=OWJKGZJg0;=KQ$%zJNiW-3Qyr3*6;vAl{2IZ%q3X9WQ*aei(q7`P19g;mS`*sRmDI;c!NPLQyuuO}4}|(+ekr;g9+f{`dHXIE-rG zkG`At#^1}kep4ud(>s0o)Ge51v}Z|}5ra32atm3VDrAK#)W;O`KXE@23-_=6eQEAv zOKqUWT(s+g%#^j0z11Z!YYS-=_b}6KTHy{UX3BDQUFoPUSc`{U&fY^UZDtHUSe4$= zv0UHQDp@jX?Uvxs)xy$BaRJRltpgO*JqdY5mYN% zHkMUUuadShR(QBCorj~uR8p80Cq_fPmYNhjt-(L$xri$-%wLFkTxXH(K$&wZw%SAa z{CO9|dLk}yV1lbc9K&Ixi7j7VdO=nYU*6F!-wB`S_eEW^h7{+0cXpJr&Kj8TCr{uE z{F6o$t$sKSmP3VRA(&|3>uYdYm#CGX8VKs=v>ty8O<;=aw1o@0V2`-k8=3x&6>^0o z#TKV7HXjWR*ctmncIz>Fw+czOgiMz1P2|1tQf! zz&3(?ZwI1H_0H-v_Tkv)lIdD=t2<_a6$3V=CdZpgnx=w5iE_$Qm5?(zyYhE84Pt9O0kI;h_7=wyrAJ$(7on|#{J zD2)qDb=wXaug~a=NLJBP_j|d??r!g2bD}A+w0Q3$yeRC;t4BDMhy|N6oV~4sm~F=8>6R~WM=@kfg`_s-v%*XJoP1W?X(1w(ilHp^ zm!QFk;59>em-Q~gx+dhO6X{0_M%L{WIsr+I?zByY4>}s9$qQ|VUWv&`WXZ|oYi533 zAqo6LJo74N`kcg$6jIo%vijt)bNZi34(=B zk8v>P-Zv2}rXDpeZCI*Ddk^yHJ>r_nD|6YCT+0J#2p6{&Yca(Nbv6>2Z&9ehmC>duK%nHVz?HgZyXqPBh>!z7^)YIO^FuT1F*43|7(yK|y zgfp2+Ef*EdxU?q~hkvq<)qf>Yqc9&!Qjx6Lcsj%K9&6ik@M$Rtwa%oO)c9N`|KrF; zePRX51sOd!!N;2$A=;RPh3puU6~^J`a-PL(jM$s*s3ixbJl-{pr8uU?3^g9Vk1}`mt`eN;uNZjNOM%E98TeU zPaL9cGY+hTlXj(}`^<<)jXy;Rer3%y+PZJ&oZ@;J<+2Lu^%v1J8yx74z!r81AS8A1 zGgg4;CHts9hJ$jh42Q(Kuom&Nxg=fHddzjX$!j`<`JAq}65a!`z(t}Odt+;?3eK|` zIPe}{MHR^kiXixY^|gh^Wp`L_u@#keesvwI^_{YboW_3W~u{ z65GIsT~xC&Iiu~tE&a%d&OO6MQY9_02OqmoM@sxzQ>Av*otOc_esBS zNlwxy4s|_?wV+eIPQR@;b#UoO$3Qi*FRCcCC} zoveMF(}I8fjFU38BhE*gv^|$)z}_dpM>~j_W`IVuM>F`!jq!5uYY)td^>4<=_%x|7 znaZYth??bxz=~v&4@&P5O7$l!r1+bL3iGqek?=@-O8DH~)xZRL-&#F)iIoI@D9V0R zFyUAG`dHjzU`Y0>-^o-nJq{`Z_33yLm`molZFx9%x+cqlTqHNgL$LdkN@Pg0jS`|$ zoQT>#Ib@{O)uPzq_QQ664w0Cz>tc5_5x{qn-F!}g^{$y{w;-?)6={ooNiw57XyX-E2?ik zQS;y8jvqv?5Hm3fxtpP5btO|6xsJakW8JNfh%g8~j~WV(fHNci(|QPIv}1kc*kNw5 z&uz&5{2p&QV=iyTPNZc1;$oB=b5T+LG|z^VHo15gf4qiRl;1~5>zYZ`h};Sv&jXQS z>KTaVr+249y${y7+O6s(zf6|79JQcqadM#K{=ek2`b~2*Gs`Qz&SY8RoO=IKCag_r z=;`M%=nfAj=?!G6{uj?eotLM^|gyp=b0xFAi&Y=BVFNz?i6X0VLo1KWR<{(xT zpBH58=eIPK1riFR-NdUQ{WiST{OOkCV!5_ElmE3WR?~;&2Xo(siZx@-KJf~8vk+BK z#K|)p+fR?ydu6#FNp5XMN#Y9UR^8Hj%I%12rLmOEDNQpfAW+7k+nN}F?i$azH)xNz z7xey-Ja=~f$6L?Z?b|!22zEZk*ET?SHN?M^MPrHzIQ-*t3sXP zvc@QMFM2~khhVWMy(IFUUY(wC`nVgXR@CoNz4sHq3yukZI@HFBoy3+MtjtF;7o2+S zdMB)$9v#xl7sNats&S1!b%AoCe5cZFhIZMS54jxnulDVJ|DMco9piQ_+G@#6n`0)i zuEzcSn`wUjd#*Y;EfG&XGw>5P3>rT_t40hl>wK1z0-LO_)R(G6&S7R_tSa=Ll}v?o zHIr7N!aMhrcGQA)U^@HNAzQnvwwF`Ollu;pEOV0BcVz2vE_3HoA!9BlYj$_~(o>_qWLnk|9d7>(1gnUC zSN=fE=w2K{ch!T+$aUCh*f!HJQ_p-;CqA;HFaaB6jG9f8(f8WayG=X8t%zVW229;PXz6jN_bK%Ywq7swlebVApr>IlbgG z16TkY7F!6u_qEvafaZPP(xH;Zl~SF>gu5ER{r;dfz4^t*ypwTz{hm)XF)b7p);PZn zI})d!Z~atsw9KC)8g#2zyxio^q}?G@@6%r=l%t#TiwmQNHZV~+NzGgC97fC}rS@2_ zGcj-wHP|2jT}r38@y_<`IE>BC=Iy%+WS2cQMHi=HuFT(OFOKRTUK-zq88(C~tg(X9 z?a>^Ky&(<oM|)Btv@UC zD2{pVBfj;CRhTJGo^8`W!E|LlXuK`9=6p^%B!fm^`pgY2yLE+qPhMAhQyz0POp6p{NP zkzdg=oyEf;23HgITJ$+*VrnP8e(|{m@98UX|G=W6WRR56cZnkW3$J}DdNG4g6!-z7%=+9feO?TvdonYdySaqtVn$oso!FqKzFz z*}AE|1*)}BdLfy!{`CTSDI&?*?@?J>71!i;Z0qfJIcTPm09bU8`MpC5?gSKDJ#wGi zhf_L9%3F)UDGt1wsiGfzNkX*|&BJ}#nAbx8LvjDRPz!Rl@h(M{#XE6hqiP_F} z(07>hYRE<{_qtar1)MQ@-#`#30_#U z-JAl5R9`Yp4mY&_QJw;sq4yd&<^R#H?spqM`iqKBUN_Pf#E||gimBR8BP@s2)mRYrr0msy4k`TqA1XYU`1M07M8Ii2P|);gOCfZmSSjG%qw*s9j*=&my3aI< zr(~lq<#b1rB*Q)|%D#K|X#FnU5+c%<0kL-79}*b2$abF&zh$m91UJIyaPb6q*zVZD zN?}noY5`+alVFB@tEH6;+(kB%UY+vfD_TEi`GSie`krD~Q=`|}hTvsMP4FX1A_@xV z;b*3sTPA`f!1b*yeQ&;Bzndo_>UmnsY;0KPzH(lqAI1SvVuHf9kIne+>@(*JV3JQs+AH-Dm`n`xfFy(2V0l!4%(rI7XbCz>J2Boo840a( zFNYW~`7Me!S#2v87q>zp8k9A?*=Uo%~ z*MH4oHGKvzv~-!hIG!*XF1-3o+;Ppw$M;M}hkyOv-2?B8Mjq>d9s{~B*I(sHyB+ri z+>n)!)sxry?GwgR8&5rYswOX3_1o)J=UMdIQ^<_0Iv^R8jW}f5RKRoe8jRR0C~4ys z7TJv+w_;t_FEX3g;wd~N$_mr9=<$?SC!@#eS6~t3{GYrI$QEXe(PKymsL_?H1hrq@ z2{XB1x~6z~Pm38$@sSnY?Yw=Vg{-jNJmGciA#Dp{tY2s^GWih`l_&`+-IZ5j}puGQq-HY$Wol{x9{>oMBVYsz}}?b-Sr zm}HUmM%V3I&@%He2)llrfX;PuCoDL#FvH&gas(w6a5;9qqU4Jy)EnS}Fvr`BIFRZ^ z42q>nplJ-PM@zYYYjggJuP6$965lon40s#l=7BXn`J&cvJ^kt#C+M4ncYBS;&UEL6 zSBCT2fQ)?nq2=PA{)QnW8BT^@RfL&rbm{&9Z{6902YVIXjpX&$Sjyw$$94Nr)Z@GT z5rRX-hIzBv?9n}C8F7|hZhN}Vn)?=k4(`&+M!wHcCr=eKUv-??!S2i~Tw)p3P|&;U z!w-!2vqOJ(bYx+mEZ||hkNXyWt|bv$o8z?skGJ$Ra@0Y|JO$`nhsM70!bmVoX0V-3 zvv^hZ!1B@QI^qa4e)AiM+;=*Vg%R+Y5+`^#WT)DGuB~q?Ukyb>+I_yS9?h{iS|-}P zpZStL-w+|x-`{_4#L!5viJNUz3N{S9m?dncAnhV)!$}&6W(=0NG z`beQgE@b}V+c&~;s*W_FsvPK&Gmo`qh6BG{&)x~To6A<7J-8}p`_{!(HdVEj`-+P< z)r`ZGZw9Dl$?w@umk;d`seN8voeD-W z2doh`9%nB1;*aH&#@6u1%IvqeXR6np9Hf^1$vfiE+PE$KL*hRvOg0-~PxpV!vtxazEBL z6L34b)vfK@H^6{)uhK>UsR(9%TF$_(TM;)1;pB3-G8NM=<9WTE=hk>`|F%1x-E@2M zZmO71XzdRIP=gh&xNnn|gBd5N{0oaluG7ULh{Ny!;p*WJJgEDgU;U=*455lBvag_2o!$W?boHd|T~fXqcl>R3a8+PFt?!@w zL9$Wg4o*~5l%h8zv$!w)ddsrwe205)OD^@HFgn={?6f<3MHPMBK-DVP7Bh9`x;CD6 za^hKaZF+I55Mv1w%Nqe#xpKwMq_phCLIh9F)w|csB+qdYnRV;d{r=Tw zRGR4ZBV&Etx6%17u-WB`^w1`Dc1pm1Tz+SYD87-xv(z=(zHDV48`eJt&T3xQ zVmmTDIf+$;jy(9?)rDWAtq_~r`{BcfS=Uh(LsVRxdE=QgbqUrh>kr}A`3qLX_IPkv zgG0Q|vQYbS@5%Y+AcY5ol!29%ygcWX(AKzz z@j0jX51H6?3B)ib$!Q(s6r-g8BmN;S8w3I|H8pi~ zaY4IJ|M~Ml?9!YM@A$es01qptq;&UPzUF$R_3En+Gh;~>so0BJII4q zSnLm|Gdgd#bqv8=OVEM0#nlyW`EM>D%{88wGPp>Q;gtHFbDo@?sTb)TNeVm3Ts^P< zV^l|EUuy5Z^9Y_$qAIb2LL%Qr6BD^wtn{VRy~;MJ>Hy}6>*#qOOMGfPxL^oL;JDfl z1jr+0-wUJd@LZyz)BJ&Fiy4CKyC5^*)KyE>lU`?j#FhkzOd@Ja*EdLJy zre&i01@B@pE6|bU)o=6_UO()r4x(syBUrT%WmkyEIM$^A`J9&w40o@gXV=!`dL|m~ zRXLMddk!u z1j=438mtt`khf&+fy;N~%jcHHosi_+M?iOl8gQ5@mrhzp7Ib-hd49z3)4p{2kb?L2 zeFB0kBh=aZ30A}LgfKWO(teAgFGIZhph)irkP9&dyhuw$$YmWb4|GTuYhA)nUT6+4 z#6=zJftUS-LUMbPv()p;dyxA`i-%M^apKn^?U0O;ehjcTsl+ZqwmooyBtN~+lK7#z zT4~bNSFBe_0lRdI0MOM&*VWlZqR}~=RcCIrpPt8lKvQQ0c%hlE_qrpH{5$OWQz5uI zn9pw9`CwUTyuz#5lrVLE@g%fV5)@TN09HQ#+t(MBnD{(3EzQj$ffL-t?Vv0Na=WGg zZj9HPQq7}_9^K0*i@cy|t(DVmKDj#@cOb~=w77hWGmu&DuHP01hbRKa-=cfZxkM+C z%dBqt@LSgVw~%4k2J98y$;eMRC={PbnF`Wdz^Pm247b0kvYU7do6d`PE=ZBX{hCFK zwa7Cc;_&QsYF@oXk2*-Z96I~UdNP}(BZ@l5ql6~H+vee?PZFc!f#;mb#xEv{PP|Y2^zXcI+s6T^kzK<4jLaQwjQh@jj9|ylUmMfHd_x;Ls}i zMFV+1U%NT>Ig^J@@qKe7DwZak0W6|`%QDZ+Y5ivHNr$wyAyH{-r|LSz zhV|{;D5HLA)t5WBZb2Ov|NIa^r%-xrf$aX4KBYycH;?W)EG#ZckLJgMqKY=hoJG6-r-C z=1C{r&m3n{txXVr1}^+mGwthw!-?H2;73V(pl58ni9Y$VIkE_QA^uX^;VU7 zeTE+>RRvyU(-BXnXICR_?hR$at|jWcCMq}H*(yGCh@@&y6Ru|2+EAEjyi63`pf^nG z<8-H^qf39VAnUR*{MuJO!Se6y57*VvvFvMOxIDv@&!PEn#F}Cfw-OO%o-w*}{c!DV z65p1eUZrhIER)Jl-F)s#yoZ(m&Zw2|N#?WbTg2vaLyi?Wz;#~|bmW2`(f&b9;2G{z{Q9psldV~II<7?EIgv(;I%Juw)F0%*X(z6KUz_=)}atl%w2X zWzg50s6+0(y$3-JmSYDcM*WL*5VRr7uMg}Brt@aUn`27X{(df^JIkoN#G})y&)0QY z3S4Vjdk@L^ZUF-^XmtISufa5kI#;j^KP_pB+FLqv^F7$|c!r`5qZF>>b=s4&;-OI2 z&^Yp^U<;3q?mlv6zx;;=y%Y~!2TETV64~uU9)I#t%f3CbvSO4V#$pN?X5nxV97*xk zcJEV)VAh?Zt8C_?=6U&$X5Xg|j z!mtQ-4p8Od58}W-QB+Nm_f2Sm`jM6^UL>w)C_rkf{Hv3I zvP{;8AL={S1Opd$h@pGfJ8#}P-kE_!{qGN)Mo^w>e>yH4CU|`7>xMhm(3&w&n`zkVxMDmeo=NsWfs_Z6to7=F1!|gmc5? zFMJlU=~{H$vF2JgGJqv94NdxrGzNpI{MkzO?8Cq8J~8sJ5Z{HZ)LhHXMrpOQD)6yQ z_&DE2QCW9~JNHTb6PeCdwH%*Q?^-qf?-aMs8r##S>hWEZmVcVbQwAHgN!Ty2b8ImD zZu)j}nYR;vwUX}Yu=OUvwtuL;Q`Mq<92`V8lo|L2@u#LD{y=k6~%em#prLLpQb$G*JaWMR?M}-6?=*nZ#!Y+399I)F(`r`t+HMQU@3Xi7+c1 zzp30}k8L8P&#-<^GCbGz^q8`)>Cjm%N)tb+`sZZ|qH8+2&W@{U{VD#m$?f;B3kif|IG#ViSD@PKoZIN?xQ_OjQMo? z9_au@=!Nd-DFo+KUYFq2KXZkrBDx_b`rJJ&n76z1=vVE{2!k>uTH7P21r4zNgCk%r z*mj3+l{aVigt+jrnPVu;rhgT0<;&!wYA>2?NkrN2s3Mh9X^t)CgX^Qm>o zC@E7!+L!~Gh3-xvDW16p<6hzsC45!=VDoA}OJQW&x5-VRF-8k1Zk(gZ{8JwjA_bv$ zwFv2xexixN%aJtMZhN3+WiU1QB{H%f1qKv|j6Sd;>g-WzWhKK;BR{dE>Mu(Q&z9=8 zRF*k2?HxsJ?dPN*HUh50<-L?J=A&&Bhn*kavYMw6?}r0kZ%gGw|4G8Z;$fxF zvQhSvpm`Hl9u5w4x~3>>n>{jR6?UMtz^Jt5v+PPOM$~Or6UXX)S)L@N^DGW2+_)CkI4?<`+PIT^sBKocF zH&KQL1ei6Nbr!;AboNTrV(lh8)aoiYSu2wl7tI@{dYahH3JVL%)9fE`;nPL1MfBsm z0=*Uka;BT=gnDnu9kck0u7zxKl=U$yrR76U8obKad!Z^36)yrUM9&j%W>~!CBdSYUTw`e&TXDWK&>W8?0UfV&@;dnl|u>e=G zq3~Bg{K{2Z$i0`h((z3SR=QSi2P~Q4*bd(D1}0w%aYJF=r&Mh{tootK3~+j8?x|z5 zu48VU2tYs8U=~FrGCd%=i>5m7EX+v3lo%yz=y^q`3*-0hp{6)gS(yt5FlBjlZxxy6_8+&?=HdCY$4twel$@P3hct^>ktA59E z^N$HohCh6XhFmwI4%gFz6YVuZ>in%uW>ER7Pi_H8r+Wq{8i|kTC@_PV zSUTP1%-=_CJl>PiD5i-OPQCV%e)+@+M0-9MjFO z{RJXfIdd@F@KO6ng%?3CIX*8z&QVv%7)`R=x`HxzYfRQp*0|FBQv%Ve6YvGf`_8vg8 z-+Z()YTYm6o1HaG(Yj2RSU^ULsItyy-{$*Bz5(lYKMVSTS0^MT2^)e#E)2h9#!WP@ z%uv1g!jB~1Ko53@S5h{10(??J0c`2MWgdl4i_N|GYYr(k<+YgV()sx(-mb}<1$GJ_ zIh?NE80}nr1DXPRkFAn1Emoi++7inqNz=S;jH0PIOed(eEADfzBPjB3XYoh_=nPMA$Dvn)eS!(HX)DQ?te>w+Hyec{)t>GvRj?9E;j>TVdT`hB{qt(Ml-gVdjOb#==PIPBtTyu2Vkaf=R?oQ3uUK*h4_-sjsf)mwimj>i)pSpLAUm0U-PMK&?g4AY-KG?u++3 zex4_GC@dL=0k2S#h%rOple;SIz%caS`}exh;1B1{**9W)mTXxBwP?&lwS(IDNW!Pv zA#dE)%>&F3QMA{O9aN~gr|LZb8eZql4l1LB@B(-k_`p!H(cO>4D;)ESi-r7Ct!fs> zpMDW!Dt+TeV+y1+hv=uyyWj-?;TD}b9}u&sab3%xn&@1^MfA)-GSu3e9`oBz{#otM zs`bGZ+b91h|D37Hj9+otq8FUgS#w=fSjenZKw?E;nAA8fko&a{SuH#)&*V?9+EriJx6f1GAD^CPy|ogD)!fE?93@bCF<@ByT)%Kj=| z%%Mw%Eo_qO_@kC(ZmKRZqoVP_axahlq`*Y^1*`Idtep1biJF0p+}vE}(|rp@<7-8fyEzG5Yb7uANye>kp85Kp>Xam!r6E^}NhDuA`(DFnND zd?-Job=eeDNeHz@6UEwixoo4yYa^W$v+XG) zejdIHfJsHFgJ(IShWUDZ2~G}?FC^MedVoixSX%d!klW$XV1?I3M?Qk%+D=qO3c0O+ zSI=h#H;N#%i@FA;0m0)wK0aWPXf*l)0)|nM&D%@J8JpQdH8nL)PtV=i<^XoP_cAhb zYin|vnsJ>@ixqv8e6}y%ym?Zo7a1N-AnJWMdv$p(*beR5C&j-D_B$dyTF12Z_djK0 zV~br8_1LD`nyBt*Yr6|zps6~yu^Oi=Ij1C`f5@Dr-UrJ8Fu0ECX&O#W&ftgSnH#m} zo#Q8&0t5uYQUFcgKjh}^e7%kryr@+}s7o5&kHc38MvTOcuk>Eo>NX8qUD8(Bn@FtY z`8F;qwCud!8!M<}Pp2)=fuOeyAJU3^42_*$$e1A1#U54noFAH1T^|BkSlfXVXs<0f zZ>w-&Q1I=k*94)r+cJRgK(y$k^~n0kXum=>hp|_IzrMdHem^-^E!FWsQE@Qz%RU2Se13b|UY#m8@h#+W z__Nn9`S{`$5;*2IH+#NI1UN@vhL+H&g0XiAo;{(aR)RtcIuG18h9e(S3q5)Iv^h&Q zTDQuUT))be%bL=XiI*21PR2RV1cT{S+oxH0tExT$7KWacHH?@^`DK7pOu2o!^y2VOFEB?Kgw9}&0vUkTfvRNL8vF=Qab$EL?Gfbc`c)CyfcB}L|5H5& zABb0YXZLenCx;eRL9ZA@<MGMhU?k@gMwGP z+3fF7;tD`MLU-T4fB(BYoYi)`B2)+LNBR*MQ#`9yfhy8cDR$wFOeGX^I9*>`n^YmH zWaw{fY@EJKE#%7VwlSRJgWbNFg!tF`^D8R}W(MuqJJ&Te0`6PmZ69%OpX_zelD{$j zSlkCxi$or4B4PK<*}gR4TA`-iO7R=ClKJ8N?GGv+A}@P@KCa3eI@LJQz|vh27e^A% zS-=9g>T@3SPL6-B9eK!iN)$$#b`XG^+gY_$&ulnO2G>(^cIKY8=e|%fTJlK6wB+_% zc^H#tW^8<1Mji=DB(G_wBNSRRYh;68ed z0Zh;cN`7Sr%Eh3pEPBIw_qMLCum{A9s|*N~_tDE2FFpbzP|sB)A5uX(=uf0J)m4{9 z5zw(qNQh8TK2Z%Qnz75Z9$dDJ&?JewJjVj64L#US_s|MQP3_x7l?UO7{Z#ANn2dv- zVviJ5r$kay^A+F>c@IK|9?t%mlj5=2E9_VYUU<7fM;jf&=Z-F z$6iIx5URiZt{qiID|m>P(l`+;Uo;HA1Q31H!GqQw-ae>Ffqpdy?DB}LH<|aXUY>HA z(B@Qq0+2GEr>0-cYP*M;uJommzqNb_yV%3SA*2!cZq^Z18`eq{(UzRClp^F{Z2Y|# zay(vXGgJuDNGMD$e}o*Yb%8J{CI6m*T^H%MHwWOIE+v3fAp%XV60|oEZ{Lfs^*be zHV-_D`AnEp-Z*VCi=9{jGjcxi@WtVv;6rLI{7U)WMwHKUVW@7@LFi|V(HUc2yK$cO zXj*hj5W$0o4_`4b1ObJJn1Z4UEq?v*7Z4YK^2vDDqb zlHhlK+~45klGPaxhm!&ygIryl;zT^>lH8%U(3pRNXI8chInC{v_#uS{+(PB@?5N+0 z2QV;G_LnmJY$8}D-Y}IkT?x(jVbeH3MOuhwZy|l=J&9aDF;MrN>0Y4Z68QSuSDPf! zl$Aowe)na1mw8gU`cLiaM)*y?5xT5wbfBQJFR;NTJQsuVI5bXEf>m_xHS7u9(8=>J z#nuPU6f?L|qH~pg#DG~?6WDs0ke0j4IG5Ls!O;}G-}%o)>{fW&l|4h0Io*4?j&Jx> zhHUgKIG>8N%k%9-EcA$NydS|kyEUm@& z*E*0lR$^7eO!gN$0k|-`w$^#LHh7~N7b~A1Z-HtY=@vSoJ32c6m(hs zo2Np1qXR^m{Q8IsY_R}fWA&GSn+!Tk9=DtJqW6`OJbr(9s+hv}$iu_K*Vp&t>U`&j z#+BQR(sBi(1714cX&OPz)Hu-tu)4jY0}nWB8g}hxiB311osa^sdN>K`c=VvZpaT&G zRX)ubA8XMa|CESG5-6&Q1rAU&RP!R%pd%(0VBK$Oz~IN1ZUdWk;h)RA+qi=t(nuTl z5_PCt$B+Yd5=Ul@u zwpUWW@lDCRC%ORmc3}6ZB$=8o=t2PDg_%FqKHTny4=@;bZY^zB*vx$ULH~Y9BEyH@Il^|hc_jbiwF(Kl%R`v@D535HfC|05X7}d7q2uQ6*kx*NZf1OB z&UteX-!xV0V|M~4p#0hwzmdV+KRC!z&yhccw!ZYyo}zZ9(bd1GPF%=(Wj151^@Q*c zxYP$T;QL~L#0c1RiM+~cZ``*hAABtd)bjqPtxW9&{(L%Sch?aB8%px>VYMwJcYk^v zEN@O!bAmh9o7{ni0EpRrK+v#}z5V1R5(z=C)0E#ZTj}OOXyvJW>&qPw?<)ZDI4^bK z?gHCzc5~A<_vc{_ETcN7lA(t_53f*!O6z@|OgqEcdiJ%^S7&5uOPJh!I`*K8>$4d( z+ilPk5E6D1RWb<7elP#b8^_sqZ)KUTwjxB0;UE(xzhz|}1}9QUlF9|97W@i7In8VR zFeUW*ItG!%Yx7L6D84h6i7eb)OPTQ-ZLORDgCMD-ZrI0<6jXxF%;*EXIs!6|Reyj! z>gwxfX(ODRoPZgnQ`yog(!-?E>5;fBO11%$aIk_V2H+XMVXXTz?|%FC%^Qy(oBGYa zs9DwH@8N2Hz&Unj1M}bDuW4y@kz6dJ@AV}X)I}@e`LVuU7{K8`Crs4w*2Kd6{Ac-` zOaL<4PS&V#=DGqcdu=0^Km`?8el71)r(T)LxiC#3AsKA8J|A?@Fj@3=N#08x;1tgy zrB3V*7-z@q@Bjue#b&syPvn1j%B06<{V_V^ts7L+1gNs0bqbpjsg3xH{e>#_GTHZH z-!n`2f⪻QNT!$NEt3#ohjj5Xm5mXWE_1CP&A6tM!b$8%XVuF3JiQgMWq-?!Ml5S zxCoGe$tIY%%2q9a3=FP;1S?au?KNd|s>S~Pwl2!M(nw|f*QeVcl($>Fx65*mNq?ry z@Ah_}b&3J-dC7UKz8a-{|Na746j@D85+>!;7hGK5s%QL#74!km4d@E-0(FU>Z@#T_ z+Xx2c2cQ&LQX!84Xu7-FPY(c&cHrN`Vk!Ieu+M6$gu0csM3Tm;Pju+FcPD@B-;YDTS}U+5v1hM(NPd%s=BR z1>kz4sYpuxfuCyhz$XE>3TO_h-5jq}C{dP{z5`SrnIi3lg@xAnw(v)ckwCoPXl+f` zSNi{8*K&*Q=Yr0!z8-%c`EQ7Hc-DI{x0qP~h+Dzo&QUh&pB-;oI&Akv<;x0S9n_TriA~$D z@$)CC;3d{)bbu9hV;T};fL#5|?ZgWZ@&Nr4un5vtSFLRAGW=@Qe0@a#^Ua{nHPmLL z_$e`QtdhdmNR#K@%dhb&h7F!-Sh13B)`x9?E_axYIn2h4q9gn-k8}WklUXe@u((h< zlqfJTu+*&MF{%zzpf%{Tv%H*(eR>UGv(=d<@y5o+n;oml?C9(~KMmjjZtHie9Z~b2?kiGtk zy50*ZIyr@BS-vasz4>xEIq7?J0fTR$omDc>86qY|1D6ldMlf)2L^7Z-p|$Za|E&fsi1_tK|=pAZp!uCK4}?2ehhQT&=7k;_!n?r&M)eFWtL{3*#F ze|_vGYq+|LaL9L_@@DIl7y&X(xyO#t{QNv1YKwU7--�R_b4EKLxagEC6*Ghuxq? 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 literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/functions.docbook b/doc/en/qalculate_kde/functions.docbook new file mode 100644 index 0000000..777fa4e --- /dev/null +++ b/doc/en/qalculate_kde/functions.docbook @@ -0,0 +1,3570 @@ + +Function List + +Algebra + + +Find Linear Function + +linearfunction(x1, y1, x2, y2) +Finds the linear function for the straight line between two distinct points. + +Arguments +x1: a free value +y1: a free value +x2: a free value +y2: a free value + + + + + +Product + +product(Factor expression, Lower limit (i), Upper limit (n)[, Index variable]) +ΠCorresponds to the product symbol. Multiplies factors for each x ranging from the lower to the upper limit. + +Arguments +Factor expression: a free value +Lower limit (i): an integer +Upper limit (n): an integer +Index variable: an unknown variable/symbol (optional, default: x) + + + +Requirement +"Upper limit (n)" >= "Lower limit (i)" + + + + + +Solve equation + +solve(Equation[, With respect to]) + +Arguments +Equation: a free value +With respect to: an unknown variable/symbol (optional, default: x) + + + + + +Solve for multiple variables + +multisolve(Equation vector, Variable vector) + +Arguments +Equation vector: a vector +Variable vector: a vector with an unknown variable/symbol, ... + + + +Requirement +dimension("Equation vector")=dimension("Variable vector") + + + + + +Solve for two variables + +solve2(Equation 1, Equation 2[, Variable 1][, Variable 2]) +Solves two equations with two unknown variables. Returns the value of the first variable. + +Arguments +Equation 1: a free value +Equation 2: a free value +Variable 1: an unknown variable/symbol (optional, default: x) +Variable 2: an unknown variable/symbol (optional, default: y) + + + + + +Sum + +sum(Term expression, Lower limit (i), Upper limit (n)[, Index variable]) +ΣCorresponds to the sum symbol. Adds terms for each x ranging from the lower to the upper limit. + +Arguments +Term expression: a free value +Lower limit (i): an integer +Upper limit (n): an integer +Index variable: an unknown variable/symbol (optional, default: x) + + + +Requirement +"Upper limit (n)" >= "Lower limit (i)" + + + + + + + +Analysis + + +Beta Function + +beta(argument 1, argument 2) + +Arguments +1: an integer +2: an integer + + + + + +Gamma Function + +gamma(argument 1) + +Arguments +1: a number + + + + + +Imaginary Part + +im(Complex number) + +Arguments +Complex number: a number + + + + + +Real Part + +re(Complex number) + +Arguments +Complex number: a number + + + + + + + +Calculus + + +Derive + +diff(Function[, With respect to][, Order]) + +Arguments +Function: a free value +With respect to: an unknown variable/symbol (optional, default: x) +Order: an integer >= 1 (optional, default: 1) + + + + + +Extreme Values + +extremum(Function[, With respect to]) + +Arguments +Function: a free value +With respect to: an unknown variable/symbol (optional, default: x) + + + + + +Integrate + +integrate(Function[, Variable of integration][, Lower limit][, Upper limit]) + +Arguments +Function: a free value +Variable of integration: an unknown variable/symbol (optional, default: x) +Lower limit: a free value (optional, default: undefined) +Upper limit: a free value (optional, default: undefined) + + + + + + + +Combinatorics + + +Binomial Coefficient + +binomial(Exponent, Index) + +Arguments +Exponent: an integer >= 1 +Index: an integer >= 0 + + + +Requirement +"Exponent">="Index" + + + + + +Combinations + +comb(Objects, Size) +Returns the number of possible arrangements of an unordered list with a number of objects to choose from and a list size. If there are three objects (1, 2 and 3) that is put in a list with place for two, the alternatives are [1, 2], [1, 3], and [2, 3], and thus the number of combinations is 3. + +Arguments +Objects: a free value +Size: a free value + + + + + +Derangements + +derangements(Number of elements) +Returns the number of possible rearrangements of an ordered list, of a certain size, where none of the objects are on their original position. If the original list is [1, 2, 3], the possible derangements is [2, 3, 1] and [3, 1, 2], and thus the number of derangements is 2. + +Arguments +Number of elements: an integer >= 1 + + + + + +Double Factorial + +factorial2(Value) +Calculates the doublefactorial of an integer. Mulitplies the argument with every second lesser positive integer (n(n-2)(n-4)...). Can also be entered as a number followed by two exclamation marks.ex. factorial2(5) = 5!! = 5 * 3 * 1 = 15 + +Arguments +Value: an integer >= -1 + + + + + +Factorial + +factorial(Value) +Calculates the factorial of an integer. Mulitplies the argument with every lesser positive integer (n(n-1)(n-2)...2*1). Can also be entered as a number followed by one exclamation mark.ex. factorial(5) = 5! = 5 * 4 * 3 * 2 * 1 = 120 + +Arguments +Value: an integer + + + + + +Hyperfactorial + +hyperfactorial(Value) +Calculates the hyperfactorial of an integer. Mulitplies the argument raised by itself with every lesser positive integer raised by themselves (1^1 * 2^2 ... n^n). ex. hyperfactorial(3) = (3^3) * (2^2) * (1^1) = 108 + +Arguments +Value: an integer >= 1 + + + + + +Multifactorial + +multifactorial(Value, Factorial) +Calculates the multifactorial of an integer. Mulitplies the argument with every x lesser positive integer (n(n-x)(n-2x)...). Can also be entered as a number followed by three or more exclamation marks.ex. multifactorial(18, 4) = 18!!!! = 18 * 14 * 10 * 6 * 2 = 30 240 + +Arguments +Value: an integer >= 0 +Factorial: an integer >= 1 + + + + + +Permutations + +perm(Objects, Size) +Returns the number of possible arrangements of an ordered list with a number of objects to choose from and a list size. If there are three objects (1, 2 and 3) that is put in a list with two positions, the alternatives are [1, 2], [2, 1], [1, 3], [3, 1], [2, 3] and [3, 2], and thus the number of permutations is 6. + +Arguments +Objects: a free value +Size: a free value + + + + + +Superfactorial + +superfactorial(Value) +Calculates the superfactorial of an integer. Mulitplies the factorial of the argument with the factorial of every lesser positive integer (1! * 2! ... n!). ex. superfactorial(5) = 5! * 4! * 3! * 2! * 1! = 34 560 + +Arguments +Value: an integer >= 0 + + + + + + + +Data Sets + + +Elements + +atom(Element[, Property]) +Retrieves data from the Elements data set for a given object and property. If "info" is typed as property, all properties of the object will be listed. +Arguments +Element: an object from "Elements" (use symbol, number, or name) +Property: name of a data property (symbol, number, name, class, or weight) (optional, default: info) + + + +Properties +Symbol: symbol (key) +Number: number (key) +Name: name (key) +Classification: classA number representing an element group:1 Alkali Metal2 Alkaline-Earth Metal3 Lanthanide4 Actinide5 Transition Metal6 Metal7 Metalloid8 Non-Metal9 Halogen10 Noble Gas11 Transactinide +Weight: weight, mass + + + + + +Planets + +planet(Planet[, Property]) +Retrieves data from the Planets data set for a given object and property. If "info" is typed as property, all properties of the object will be listed.This data uses material from the Wikipedia articles"Earth" (http://www.wikipedia.org/wiki/Earth),"Jupiter (planet)" (http://www.wikipedia.org/wiki/Jupiter_(planet)),"Mars (planet)" (http://www.wikipedia.org/wiki/Mars_(planet)),"Mercury (planet)" (http://www.wikipedia.org/wiki/Mercury_(planet)),"Neptune (planet)" (http://www.wikipedia.org/wiki/Neptune_(planet)),"Pluto (planet)" (http://www.wikipedia.org/wiki/Pluto_(planet)),"Saturn (planet)" (http://www.wikipedia.org/wiki/Saturn_(planet)),"Uranus (planet)" (http://www.wikipedia.org/wiki/Uranus_(planet)), and"Venus (planet)" (http://en.wikipedia.org/wiki/Venus_(planet)),licensed under the GNU Free Documentation License (http://www.gnu.org/copyleft/fdl.html) + +Arguments +Planet: an object from "Planets" (use name) +Property: name of a data property (name, year, speed, eccentricity, inclination, satellites, mass, density, area, gravity, or temperature) (optional, default: info) + + + +Properties +Name: name (key) +Orbital Period (Year): year +Average Orbital Speed: speed +Eccentricity: eccentricity +Inclination: inclination +Number of Satellites: satellites +Mass: mass +Mean Density: density +Surface Area: area +Equatorial Gravity: gravity +Mean Surface Temperature: temperature + + + + + + + +Date & Time + + +Current Time + +time() + + + +Date to Unix Timestamp + +timestamp([Date]) + +Arguments +Date: a date (optional, default: now) + + + + + +Day of Month + +day([Date]) + +Arguments +Date: a date (optional, default: today) + + + + + +Day of Week + +weekday([Date][, Week begins on Sunday]) + +Arguments +Date: a date (optional, default: today) +Week begins on Sunday: a boolean (0 or 1) (optional, default: 0) + + + + + +Day of Year + +yearday([Date]) + +Arguments +Date: a date (optional, default: today) + + + + + +Days between two dates + +days(First date, Second date[, Day counting basis][, Financial function mode]) +Returns the number of days between two dates.Basis is the type of day counting you want to use: 0: US 30/360, 1: real days (default), 2: real days/360, 3: real days/365 or 4: European 30/360. + +Arguments +First date: a date +Second date: a date +Day counting basis: an integer >= 0 and <= 4 (optional, default: 1) +Financial function mode: a boolean (0 or 1) (optional, default: 0) + + + + + +Local Date Format + +localdate([Date]) + +Arguments +Date: a date (optional, default: today) + + + + + +Month + +month([Date]) + +Arguments +Date: a date (optional, default: today) + + + + + +Standard Date Format + +isodate([Date]) + +Arguments +Date: a date (optional, default: today) + + + + + +Unix Timestamp to Date + +stamptodate(Timestamp) + +Arguments +Timestamp: an integer + + + + + +Week of Year + +week([Date][, Week begins on Sunday]) + +Arguments +Date: a date (optional, default: today) +Week begins on Sunday: a boolean (0 or 1) (optional, default: 0) + + + + + +Year + +year([Date]) + +Arguments +Date: a date (optional, default: today) + + + + + +Years between two dates + +yearfrac(First date, Second date[, Day counting basis][, Financial function mode]) +Returns the number of years (fractional) between two dates.Basis is the type of day counting you want to use: 0: US 30/360, 1: real days (default), 2: real days/360, 3: real days/365 or 4: European 30/360. + +Arguments +First date: a date +Second date: a date +Day counting basis: an integer >= 0 and <= 4 (optional, default: 1) +Financial function mode: a boolean (0 or 1) (optional, default: 0) + + + + + + + +Economics + +Finance + + +Accrued interest of security paying at maturity + +accrintm(Issue date, Settlement date, Annual rate of security[, Par value][, Day counting basis]) +Returns the accrued interest for a security which pays interest at maturity date.Basis is the type of day counting you want to use: 0: US 30/360 (default), 1: real days, 2: real days/360, 3: real days/365 or 4: European 30/360. + +Arguments +Issue date: a date +Settlement date: a date +Annual rate of security: a free value +Par value: a free value (optional, default: 1000) +Day counting basis: an integer >= 0 and <= 4 (optional, default: 0) + + + + + +Accrued interest of security with periodic interest payments + +accrint(Issue date, First interest, Settlement date, Annual rate of security, Par value, Frequency[, Day counting basis]) +Returns accrued interest for a security which pays periodic interest.Allowed frequencies are 1 - annual, 2 - semi-annual or 4 - quarterly. Basis is the type of day counting you want to use: 0: US 30/360 (default), 1: real days, 2: real days/360, 3: real days/365 or 4: European 30/360. + +Arguments +Issue date: a date +First interest: a date +Settlement date: a date +Annual rate of security: a free value +Par value: a free value +Frequency: an integer >= 1 and <= 4 +Day counting basis: an integer >= 0 and <= 4 (optional, default: 0) + + + + + +Amount received at maturity for a security bond + +received(Settlement date, Maturity date, Investment, Discount rate[, Day counting basis]) +Returns the amount received at the maturity date for an invested security.Basis is the type of day counting you want to use: 0: US 30/360 (default), 1: real days, 2: real days/360, 3: real days/365 or 4: European 30/360. The settlement date must be before maturity date. + +Arguments +Settlement date: a date +Maturity date: a date +Investment: a free value +Discount rate: a free value +Day counting basis: an integer >= 0 and <= 4 (optional, default: 0) + + + + + +Compound + +compound(Principal, Nominal interest rate, Periods per year, Years) +Returns the value of an investment, given the principal, nominal interest rate, compounding frequency and time. + +Arguments +Principal: a free value +Nominal interest rate: a free value +Periods per year: a free value +Years: a free value + + + + + +Discount rate for a security + +disc(Settlement date, Maturity date, Price per $100 face value, Redemption[, Day counting basis]) +Returns the discount rate for a security.Basis is the type of day counting you want to use: 0: US 30/360 (default), 1: real days, 2: real days/360, 3: real days/365 or 4: European 30/360. + +Arguments +Settlement date: a date +Maturity date: a date +Price per $100 face value: a free value +Redemption: a free value +Day counting basis: an integer >= 0 and <= 4 (optional, default: 0) + + + + + +Dollar Decimal + +dollarde(Fractional dollar, Denominator of fraction) +Converts a dollar price expressed as a fraction into a dollar price expressed as a decimal number. + +Arguments +Fractional dollar: a free value +Denominator of fraction: an integer >= 1 + + + + + +Dollar Fraction + +dollarfr(Decimal dollar, Denominator of fraction) +Converts a decimal dollar price into a dollar price expressed as a fraction. + +Arguments +Decimal dollar: a free value +Denominator of fraction: an integer >= 1 + + + + + +Effective Interest Rate + +effect(Nominal interest rate, Periods) +Calculates the effective interest for a given nominal rate. + +Arguments +Nominal interest rate: a free value +Periods: a free value + + + + + +Future Value + +fv(Interest rate, Number of periods, Payment made each period[, Present value][, Type]) +Computes the future value of an investment. This is based on periodic, constant payments and a constant interest rate.If type = 1 then the payment is made at the beginning of the period, If type = 0 (or omitted) it is made at the end of each period. + +Arguments +Interest rate: a free value +Number of periods: a free value +Payment made each period: a free value +Present value: a free value (optional, default: 0) +Type: a boolean (0 or 1) (optional, default: 0) + + + + + +Interest paid on a given period of an investment (ISPMT) + +ispmt(Periodic interest rate, Amortizement period, Number of periods, Present value) +Calculates the interest paid on a given period of an investment. + +Arguments +Periodic interest rate: a free value +Amortizement period: an integer >= 1 +Number of periods: an integer >= 1 +Present value: a free value + + + + + +Interest rate for a fully invested security + +intrate(Settlement date, Maturity date, Investment, Redemption[, Day counting basis]) +Returns the interest rate for a fully invested security.Basis is the type of day counting you want to use: 0: US 30/360 (default), 1: real days, 2: real days/360, 3: real days/365 or 4: European 30/360. + +Arguments +Settlement date: a date +Maturity date: a date +Investment: a free value +Redemption: a free value +Day counting basis: an integer >= 0 and <= 4 (optional, default: 0) + + + + + +Level-Coupon Bond + +level_coupon(Face value, Coupon rate, Coupons per year, Years, Market interest rate) +Calculates the value of a level-coupon bond. + +Arguments +Face value: a free value +Coupon rate: a free value +Coupons per year: a free value +Years: a free value +Market interest rate: a free value + + + + + +Nominal Interest Rate + +nominal(Effective interest rate, Periods) +Calculates the nominal interest rate from a given effective interest rate compounded at given intervals. + +Arguments +Effective interest rate: a free value +Periods: a free value + + + + + +Number of coupons to be paid + +coupnum(Settlement date, Maturity date, Frequency[, Day counting basis]) +Returns the number of coupons to be paid between the settlement and the maturity.Basis is the type of day counting you want to use: 0: US 30/360 (default), 1: real days, 2: real days/360, 3: real days/365 or 4: European 30/360. + +Arguments +Settlement date: a date +Maturity date: a date +Frequency: an integer >= 1 and <= 12 +Day counting basis: an integer >= 0 and <= 4 (optional, default: 0) + + + + + +Payment for a loan + +pmt(Rate, Number of periods, Present value[, Future value][, Type]) +Returns the amount of payment for a loan based on a constant interest rate and constant payments (each payment is equal amount).If type = 1 then the payment is made at the beginning of the period, If type = 0 (or omitted) it is made at the end of each period. + +Arguments +Rate: a free value +Number of periods: a free value +Present value: a free value +Future value: a free value (optional, default: 0) +Type: a boolean (0 or 1) (optional, default: 0) + + + + + +Payment of an annuity going towards interest (IPMT) + +ipmt(Periodic interest rate, Period, Number of periods, Present value[, Future value][, Type]) +Calculates the amount of a payment of an annuity going towards interest.Type defines the due date. 1 for payment at the beginning of a period and 0 (default) for payment at the end of a period. + +Arguments +Periodic interest rate: a free value +Period: an integer >= 1 +Number of periods: an integer >= 1 +Present value: a free value +Future value: a free value (optional, default: 0) +Type: a boolean (0 or 1) (optional, default: 0) + + + + + +Payment of an annuity going towards principal (PPMT) + +ppmt(Periodic interest rate, Amortizement period, Number of periods, Present value[, Desired future value][, Type]) +Calculates the amount of a payment of an annuity going towards principal.Type defines the due date. 1 for payment at the beginning of a period and 0 (default) for payment at the end of a period. + +Arguments +Periodic interest rate: a free value +Amortizement period: an integer >= 1 +Number of periods: an integer >= 1 +Present value: a free value +Desired future value: a free value (optional, default: 0) +Type: a boolean (0 or 1) (optional, default: 0) + + + + + +Periods for investment to attain desired value + +g_duration(Rate, Present value, Future value) +Returns the number of periods needed for an investment to attain a desired value. + +Arguments +Rate: a free value +Present value: a free value +Future value: a free value + + + + + +Periods of an investment + +nper(Interest rate, Payment made each period, Present value[, Future value][, Type]) +Calculates number of periods of an investment based on periodic constant payments and a constant interest rate.Type defines the due date. 1 for payment at the beginning of a period and 0 (default) for payment at the end of a period. + +Arguments +Interest rate: a free value +Payment made each period: a free value +Present value: a free value +Future value: a free value (optional, default: 0) +Type: a free value (optional, default: 0) + + + + + +Present Value + +pv(Interest rate, Number of periods, Payment made each period[, Future value][, Type]) +Returns the present value of an investment.If type = 1 then the payment is made at the beginning of the period, If type = 0 (or omitted) it is made at the end of each period. + +Arguments +Interest rate: a free value +Number of periods: a free value +Payment made each period: a free value +Future value: a free value (optional, default: 0) +Type: a boolean (0 or 1) (optional, default: 0) + + + + + +Price per $100 face value of a security + +pricemat(Settlement date, Maturity date, Issue date, Discount rate, Annual yield[, Day counting basis]) +Calculates and returns the price per $100 face value of a security. The security pays interest at maturity.Basis is the type of day counting you want to use: 0: US 30/360 (default), 1: real days, 2: real days/360, 3: real days/365 or 4: European 30/360. + +Arguments +Settlement date: a date +Maturity date: a date +Issue date: a date +Discount rate: a free value +Annual yield: a free value +Day counting basis: an integer >= 0 and <= 4 (optional, default: 0) + + + + + +Price per $100 face value of a security bond + +pricedisc(Settlement date, Maturity date, Discount, Redemption[, Day counting basis]) +Calculates and returns the price per $100 face value of a security bond. The security does not pay interest at maturity.Basis is the type of day counting you want to use: 0: US 30/360 (default), 1: real days, 2: real days/360, 3: real days/365 or 4: European 30/360. + +Arguments +Settlement date: a date +Maturity date: a date +Discount: a free value +Redemption: a free value +Day counting basis: an integer >= 0 and <= 4 (optional, default: 0) + + + + + +Return on continuously compounded interest + +continuous(Principal, Interest rate, Years) +Calculates the return on continuously compounded interest, given the principal, nominal rate and time in years. + +Arguments +Principal: a free value +Interest rate: a free value +Years: a free value + + + + + +Straight Line Depreciation + +sln(Cost, Salvage value, Life) +Determines the straight line depreciation of an asset for a single period.Cost is the amount you paid for the asset. Salvage is the value of the asset at the end of the period. Life is the number of periods over which the asset is depreciated. SLN divides the cost evenly over the life of an asset. + +Arguments +Cost: a free value +Salvage value: a free value +Life: a free value + + + + + +Sum-of-Years Digits Depreciation + +syd(Cost, Salvage value, Life, Period) +Calculates the sum-of-years digits depreciation for an asset based on its cost, salvage value, anticipated life, and a particular period. This method accelerates the rate of the depreciation, so that more depreciation expense occurs in earlier periods than in later ones. The depreciable cost is the actual cost minus the salvage value. The useful life is the number of periods (typically years) over which the asset is depreciated. + +Arguments +Cost: a free value +Salvage value: a free value +Life: a free value +Period: a free value + + + + + +Treasury Bill Equivalent + +tbilleq(Settlement date, Maturity date, Discount rate) +Returns the bond equivalent for a treasury bill. + +Arguments +Settlement date: a date +Maturity date: a date +Discount rate: a free value + + + + + +Treasury Bill Price + +tbillprice(Settlement date, Maturity date, Discount rate) +Returns the price per $100 value for a treasury bill. + +Arguments +Settlement date: a date +Maturity date: a date +Discount rate: a free value + + + + + +Treasury Bill Yield + +tbillyield(Settlement date, Maturity date, Price per $100 face value) +Returns the yield for a treasury bill. + +Arguments +Settlement date: a date +Maturity date: a date +Price per $100 face value: a free value + + + + + +Zero Coupon + +zero_coupon(Face value, Interest rate, Years) +Calculates the value of a zero-coupon (pure discount) bond. + +Arguments +Face value: a free value +Interest rate: a free value +Years: a free value + + + + + + + +Microeconomics + + +Elasticity + +elasticity(Demand function, Price[, Price variable]) +Calculates the demand elesticity. Also works for supply elasticity, income elasticity, cross-price elasticity, etc. Just replace demand, with supply, or price with income...Ex. elasticity(100-x^2, 3) calculates the demand elasticity when the price is 3 for the function "Q = 100 - x^2" where x is the default price variable. + +Arguments +Demand function: a free value +Price: a free value +Price variable: an unknown variable/symbol (optional, default: x) + + + + + + + + +Exponents & Logarithms + + +10 raised the to power X + +exp10(Exponent) + +Arguments +Exponent: a free value + + + + + +2 raised the to power X + +exp2(Exponent) + +Arguments +Exponent: a free value + + + + + +Base-10 Logrithm + +log10(Value) +Returns the base n logarithm. + +Arguments +Value: a number >= 0 + + + + + +Base-2 Logrithm + +log2(Value) +Returns the base n logarithm. + +Arguments +Value: a number >= 0 + + + + + +Base-N Logarithm + +log(Value[, Base]) + +Arguments +Value: a number that is nonzero +Base: a number that is nonzero (optional, default: e) + + + + + +Complex Exponential (Cis) + +cis(Exponent) + +Arguments +Exponent: a free value + + + + + +Cube Root + +cbrt(Value) + +Arguments +Value: a free value + + + + + +Exponential (e^x) + +exp(Exponent) + +Arguments +Exponent: a free value + + + + + +Natural Logarithm + +ln(Value) + +Arguments +Value: a number that is nonzero + + + + + +Nth root + +root(Base, Exponent) + +Arguments +Base: a free value +Exponent: a free value + + + + + +Square + +sq(Value) + +Arguments +Value: a free value + + + + + +Square Root + +sqrt(Value) + +Arguments +Value: a free value + + + + + +Square root (x * pi) + +sqrtpi(Non-negative value) +Returns the non-negative square root of x * pi + +Arguments +Non-negative value: a number >= 0 + + + + + +X raised to the power Y + +pow(Base, Exponent) + +Arguments +Base: a free value +Exponent: a free value + + + + + + + +Geometry + +Circle + + +Circle Area + +circle(Radius) +Calculates the area of a circle using the radius + +Arguments +Radius: a free value + + + + + +Circle Circumference + +circumference(Radius) +Calculates the area of a circle using the radius + +Arguments +Radius: a free value + + + + + + + +Cone + + +Cone Volume + +cone(Radius, Height) + +Arguments +Radius: a free value +Height: a free value + + + + + +Surface Area of Cone + +cone_sa(Radius, Height) + +Arguments +Radius: a free value +Height: a free value + + + + + + + +Cube + + +Cube Volume + +cube(Length of side) + +Arguments +Length of side: a free value + + + + + +Surface Area of Cube + +cube_sa(Length of side) + +Arguments +Length of side: a free value + + + + + + + +Cylinder + + +Cylinder Volume + +cylinder(Radius, Height) + +Arguments +Radius: a free value +Height: a free value + + + + + +Surface Area of Cylinder + +cylinder_sa(Radius, Height) + +Arguments +Radius: a free value +Height: a free value + + + + + + + +Parallelogram + + +Parallelogram Area + +parallelogram(Base, Height) +Calculates the area of a four-sided figure whose opposite sides are both parallel and equal in length. + +Arguments +Base: a free value +Height: a free value + + + + + +Parallelogram Perimeter + +parallelogram_perimeter(Side A, Side B) +Calculates the perimeter of a four-sided figure whose opposite sides are both parallel and equal in length. + +Arguments +Side A: a free value +Side B: a free value + + + + + + + +Prism + + +Surface Area of Rectangular Prism + +rectprism_sa(Length, Width, Height) +Calculates the surface area of a prism with rectangular base. + +Arguments +Length: a free value +Width: a free value +Height: a free value + + + + + +Volume of Rectangular Prism + +rectprism(Length, Width, Height) +Calculates the volume of a prism with rectangular base. + +Arguments +Length: a free value +Width: a free value +Height: a free value + + + + + +Volume of Triangular Prism + +triangleprism(Length, Width, Height) +Calculates the volume of a prism with triangular base. + +Arguments +Length: a free value +Width: a free value +Height: a free value + + + + + + + +Pyramid + + +Height of Regular Tetrahedron + +tetrahedron_height(Length of side) + +Arguments +Length of side: a free value + + + + + +Height of Square Pyramid + +sqpyramid_height(Length of side) + +Arguments +Length of side: a free value + + + + + +Pyramid Volume + +pyramid(Length of base, Width of base, Height) +Calculates the volume of a 3-dimensional shape standing on a rectangular base and terminating in a point at the top. + +Arguments +Length of base: a free value +Width of base: a free value +Height: a free value + + + + + +Surface Area of Regular Tetrahedron + +tetrahedron_sa(Length of side) + +Arguments +Length of side: a free value + + + + + +Surface Area of Square Pyramid + +sqpyramid_sa(Length of side) + +Arguments +Length of side: a free value + + + + + +Volume of Regular Tetrahedron + +tetrahedron(Length of side) + +Arguments +Length of side: a free value + + + + + +Volume of Square Pyramid + +sqpyramid(Length of side) + +Arguments +Length of side: a free value + + + + + + + +Rectangle + + +Rectangle Area + +rect(Length, Width) + +Arguments +Length: a free value +Width: a free value + + + + + +Rectangle Perimeter + +rect_perimeter(Length, Width) + +Arguments +Length: a free value +Width: a free value + + + + + + + +Sphere + + +Sphere Volume + +sphere(Radius) + +Arguments +Radius: a free value + + + + + +Surface Area of Sphere + +sphere_sa(Radius) + +Arguments +Radius: a free value + + + + + + + +Square + + +Square Area + +square(Length of side) + +Arguments +Length of side: a free value + + + + + +Square Perimeter + +square_perimeter(Length of side) + +Arguments +Length of side: a free value + + + + + + + +Trapezoid + + +Trapezoid Area + +trapezoid(Side A, Side B, Height) +Calculates the area of a four-sided figure with two parallel sides. + +Arguments +Side A: a free value +Side B: a free value +Height: a free value + + + + + + + +Triangle + + +Hypotenuse + +hypot(Side A, Side B) + +Arguments +Side A: a free value +Side B: a free value + + + + + +Triangle Area + +triangle(Base, Height) + +Arguments +Base: a free value +Height: a free value + + + + + +Triangle Perimeter + +triangle_perimeter(Side A, Side B) + +Arguments +Side A: a free value +Side B: a free value + + + + + + + + +Logical + + +Bitwise Exclusive OR + +bitxor(Value 1, Value 2) + +Arguments +Value 1: an integer or a vector +Value 2: an integer or a vector + + + + + +Bitwise Shift + +shift(Number, Bits) + +Arguments +Number: an integer +Bits: an integer + + + + + +For...Do + +for(Initial value of counter, Counter variable, For condition, Counter update function, Initial value, Do function, Value variable) + +Arguments +Initial value of counter: a free value +Counter variable: an unknown variable/symbol +For condition: a free value +Counter update function: a free value +Initial value: a free value +Do function: a free value +Value variable: an unknown variable/symbol + + + + + +If...Then...Else + +if(Condition, Expression if condition is met, Expression if condition is NOT met) +Tests a condition and returns a value depending on the result. + +Arguments +Condition: a real number +Expression if condition is met: a free value +Expression if condition is NOT met: a free value + + + + + +Logical Exclusive OR + +xor(Value 1, Value 2) + +Arguments +Value 1: a free value +Value 2: a free value + + + + + + + +Matrices & Vectors + + +Adjugate (Adjoint) + +adj(Matrix) +Calculates the adjugate or adjoint of a matrix. + +Arguments +Matrix: a square matrix + + + + + +Cofactor + +cofactor(Matrix, Row, Column) +Calculates the cofactor of the element at specified position. + +Arguments +Matrix: a matrix +Row: an integer >= 1 +Column: an integer >= 1 + + + + + +Columns + +columns(Matrix) +Returns the number of columns in a matrix. + +Arguments +Matrix: a matrix + + + + + +Construct Matrix + +matrix(Rows, Columns, Elements) +Returns a matrix with specified dimensions and listed elements. Omitted elements are set to zero. + +Arguments +Rows: an integer >= 1 +Columns: an integer >= 1 +Elements: a vector + + + + + +Construct Vector + +vector([argument 1], ...) +Returns a vector with listed elements. + +Arguments +1: a free value (optional) + + + + + +Convert Matrix to Vector + +matrix2vector(Matrix) +Puts each element of a matrix in vertical order in a vector. + +Arguments +Matrix: a matrix + + + + + +Cross Product + +cross(Vector 1, Vector 2) +Calculates the cross product of a 3-dimensional vector. + +Arguments +Vector 1: a vector that fulfills the condition: "dimension(\x)==3" +Vector 2: a vector that fulfills the condition: "dimension(\x)==3" + + + + + +Determinant + +det(Matrix) +Calculates the determinant of a matrix. + +Arguments +Matrix: a square matrix + + + + + +Dimension + +dimension(Vector) +Returns the number of elements in a vector. + +Arguments +Vector: a vector + + + + + +Element + +element(Matrix/vector, Row/index[, Column]) +Returns the element at specified position in a matrix (row and column) or vector (index). + +Arguments +Matrix/vector: a vector +Row/index: an integer >= 1 +Column: an integer (optional, default: 0) + + + + + +Elements + +elements(Matrix or vector) +Returns the number of elements in a matrix or vector. + +Arguments +Matrix or vector: a vector + + + + + +Export To CSV File + +export(Matrix/vector, Filename[, Separator]) +Exports a matrix to a CSV data file. + +Arguments +Matrix/vector: a vector +Filename: a valid file name +Separator: a text string (optional, default: ,) + + + + + +Extract Column as Vector + +column(Matrix, Column) +Returns a column in a matrix as a vector. + +Arguments +Matrix: a matrix +Column: an integer >= 1 + + + + + +Extract row as vector + +row(Matrix, Row) +Returns a row in a matrix as a vector. + +Arguments +Matrix: a matrix +Row: an integer >= 1 + + + + + +Generate Vector + +genvector(Function, Min, Max, Dimension / Step size[, Variable][, Use step size]) +Returns a vector generated from a function with a variable (default x) running from min to max. The fourth argument is either the requested number of elements if the sixth argument is false (default) or the step between each value of the variable. + +Arguments +Function: a free value +Min: a free value +Max: a free value +Dimension / Step size: a free value +Variable: an unknown variable/symbol (optional, default: x) +Use step size: a boolean (0 or 1) (optional, default: 0) + + + + + +Identity + +identity(Matrix or rows/columns) +Returns the identity matrix of a matrix or with specified number of rows/columns. + +Arguments +Matrix or rows/columns: an integer >= 1 or a square matrix + + + + + +Load CSV File + +load(Filename[, First data row][, Separator]) +Returns a matrix imported from a CSV data file. + +Arguments +Filename: a valid file name +First data row: an integer >= 1 (optional, default: 1) +Separator: a text string (optional, default: ,) + + + + + +Matrix Area + +area(Matrix, Start row, Start column, End row, End column) +Returns a part of a matrix. + +Arguments +Matrix: a matrix +Start row: an integer >= 1 +Start column: an integer >= 1 +End row: an integer >= 1 +End column: an integer >= 1 + + + + + +Matrix Inverse + +inverse(Matrix) +Calculates the inverse of a matrix. The inverse is the matrix that multiplied by the original matrix equals the identity matrix (AB = BA = I). + +Arguments +Matrix: a square matrix + + + + + +Merge Vectors + +mergevectors(Vector 1[, Vector 2], ...) +Returns a vector with the elements from two vectors. + +Arguments +Vector 1: a vector +Vector 2: a vector (optional) + + + + + +Norm (length) + +norm(Vector) +Calculates the norm/length of a vector. + +Arguments +Vector: a vector + + + + + +Permanent + +permanent(Matrix) +Calculates the permanent of a matrix. The permanent differs from a determinant in that all signs in the expansion by minors are taken as positive. + +Arguments +Matrix: a square matrix + + + + + +Rank + +rank(Vector[, Ascending]) +Returns a vector with values of elements replaced with their mutual ranks.ex. rank([6, 1, 4]) = [3, 1, 2] + +Arguments +Vector: a vector +Ascending: a boolean (0 or 1) (optional, default: 1) + + + + + +Rows + +rows(Matrix) +Returns the number of rows in a matrix. + +Arguments +Matrix: a matrix + + + + + +Sort + +sort(Vector[, Ascending]) +Returns a sorted vector.ex. sort([6, 1, 4])=[1, 4, 6] + +Arguments +Vector: a vector +Ascending: a boolean (0 or 1) (optional, default: 1) + + + + + +Transpose + +transpose(Matrix) +Returns the transpose of a matrix. + +Arguments +Matrix: a matrix + + + + + +Vector Limits + +limits(Vector, Lower limit, Upper limit) +Returns a part of a vector between two positions. + +Arguments +Vector: a vector +Lower limit: an integer +Upper limit: an integer + + + + + + + +Miscellaneous + + +Body Mass Index (BMI) + +bmi(Weight, Length) +Calculates the Body Mass Index. The resulting BMI-value is sometimes interpreted as follows (although varies with age, sex, etc.):Underweight < 18.5Normal weight 18.5-25Overweight 25-30Obesity > 30Note that you must use units for weight (ex. 59kg) and length (ex. 174cm). + +Arguments +Weight: a free value +Length: a free value + + + + + +Kronecker Delta + +kronecker(Value 1 (i)[, Value 2 (j)]) +Returns 0 if i != j and 1 if i = j. + +Arguments +Value 1 (i): a real number +Value 2 (j): a real number (optional, default: 0) + + + + + +Riemann Zeta + +zeta(Integral point) + +Arguments +Integral point: an integer >= 1 and <= 2.1474836E9 + + + + + +Roman Number + +roman(Roman number) + +Arguments +Roman number: a text string + + + + + + + +Number Theory + + +Absolute Value + +abs(Value) + +Arguments +Value: a number + + + + + +Greatest Common Divisor + +gcd(1st value, 2nd value) + +Arguments +1st value: a free value that is rational (polynomial) +2nd value: a free value that is rational (polynomial) + + + + + +Least Common Multiplier + +lcm(1st value, 2nd value) + +Arguments +1st value: a free value that is rational (polynomial) +2nd value: a free value that is rational (polynomial) + + + + + + +Arithmetics + + +Add + +add(Terms) + +Arguments +Terms: a vector + + + + + +Denominator + +denominator(Number) + +Arguments +Number: a rational number + + + + + +Divide + +divide(Numerator, Denominator) + +Arguments +Numerator: a free value +Denominator: a free value + + + + + +Modulus + +mod(Numerator, Denominator) + +Arguments +Numerator: a real number +Denominator: a real number that is nonzero + + + + + +Multiply + +multiply(Factors) + +Arguments +Factors: a vector + + + + + +Negate + +neg(Value) + +Arguments +Value: a free value + + + + + +Numerator + +numerator(Number) + +Arguments +Number: a rational number + + + + + +Raise + +raise(Base, Exponent) + +Arguments +Base: a free value +Exponent: a free value + + + + + +Reciprocal + +inv(Value) + +Arguments +Value: a free value + + + + + +Remainder + +rem(Numerator, Denominator) + +Arguments +Numerator: a real number +Denominator: a real number that is nonzero + + + + + +Signum + +sgn(Number) + +Arguments +Number: a number + + + + + +Subtract + +subtract(Terms) + +Arguments +Terms: a vector + + + + + + + +Integers + + +Even + +even(Number) + +Arguments +Number: an integer + + + + + +Odd + +odd(Number) + +Arguments +Number: an integer + + + + + + + +Number Bases + + +Binary + +bin(Binary number) +Returns a decimal integer from a binary number + +Arguments +Binary number: a text string + + + + + +Hexadecimal + +hex(Hexadecimal number) +Returns a decimal value from a hexadecimal number + +Arguments +Hexadecimal number: a text string + + + + + +Number Base + +base(Number, Base) +Returns a decimal integer from a number of specified base between 2 and 36 + +Arguments +Number: a text string +Base: an integer >= 2 and <= 36 + + + + + +Octal + +oct(Octal number) +Returns a decimal integer from an octal number + +Arguments +Octal number: a text string + + + + + + + +Polynomials + + +Coefficient + +coeff(Polynomial, Number[, Variable]) + +Arguments +Polynomial: a free value that is rational (polynomial) +Number: an integer >= 0 +Variable: an unknown variable/symbol (optional, default: x) + + + + + +Content Part + +pcontent(Polynomial[, Variable]) + +Arguments +Polynomial: a free value that is rational (polynomial) +Variable: an unknown variable/symbol (optional, default: x) + + + + + +Leading Coefficient + +lcoeff(Polynomial[, Variable]) + +Arguments +Polynomial: a free value that is rational (polynomial) +Variable: an unknown variable/symbol (optional, default: x) + + + + + +Lowest Degree (Valuation) + +ldegree(Polynomial[, Variable]) + +Arguments +Polynomial: a free value that is rational (polynomial) +Variable: an unknown variable/symbol (optional, default: x) + + + + + +Polynomial Degree + +degree(Polynomial[, Variable]) + +Arguments +Polynomial: a free value that is rational (polynomial) +Variable: an unknown variable/symbol (optional, default: x) + + + + + +Primitive Part + +primpart(Polynomial[, Variable]) + +Arguments +Polynomial: a free value that is rational (polynomial) +Variable: an unknown variable/symbol (optional, default: x) + + + + + +Trailing Coefficient + +tcoeff(Polynomial[, Variable]) + +Arguments +Polynomial: a free value that is rational (polynomial) +Variable: an unknown variable/symbol (optional, default: x) + + + + + +Unit Part + +punit(Polynomial[, Variable]) + +Arguments +Polynomial: a free value that is rational (polynomial) +Variable: an unknown variable/symbol (optional, default: x) + + + + + + + +Rounding + + +Extract Fractional Part + +frac(Value) + +Arguments +Value: a real number + + + + + +Extract Integer Part + +int(Value) + +Arguments +Value: a real number + + + + + +Round + +round(Value) + +Arguments +Value: a real number + + + + + +Round Downwards + +floor(Value) + +Arguments +Value: a real number + + + + + +Round Towards Zero + +trunc(Value) + +Arguments +Value: a real number + + + + + +Round Upwards + +ceil(Value) + +Arguments +Value: a real number + + + + + + + + +Statistics + + +Random Number + +rand([Ceil]) +Generates a pseudo-random number. Returns a real number between 0 and 1, if ceil is zero (default), or an integer between 1 and (including) ceil. + +Arguments +Ceil: an integer (optional, default: -1) + + + + + +Random Number Between Limits + +randbetween(Bottom, Top) +Returns an integer between (including) bottom and top. + +Arguments +Bottom: an integer +Top: an integer + + + +Requirement +"Bottom"<="Top" + + + + + + +Descriptive Statistics + + +Decile + +decile(Data, Decile) + +Arguments +Data: a vector +Decile: a number >= 0 and <= 100 + + + + + +Interquartile Range + +iqr(Data) +Calculates the difference between the first and third quartile. + +Arguments +Data: a vector + + + + + +Max + +max(Vector) +Returns the highest value. + +Arguments +Vector: a vector + + + + + +Median + +median(Data) + +Arguments +Data: a vector + + + + + +Min + +min(Vector) +Returns the lowest value. + +Arguments +Vector: a vector + + + + + +Mode + +mode(Vector) +Returns the most frequently occuring value. + +Arguments +Vector: a vector + + + + + +Number of Samples + +number(Data) +Returns the number of samples. + +Arguments +Data: a vector + + + + + +Percentile + +percentile(Vector, Percentile (%)) + +Arguments +Vector: a vector +Percentile (%): a number > 0 and < 99 + + + + + +Quartile + +quartile(Data, Quartile) + +Arguments +Data: a vector +Quartile: an integer >= 1 and <= 3 + + + + + +Range + +range(Data) +Calculates the difference between the min and max value. + +Arguments +Data: a vector + + + + + +Sum (total) + +total(Data) + +Arguments +Data: a vector + + + + + + + +Distribution + + +Logistic Distribution + +logistic(X, Scale) +Returns the probability density p(x) at x for a logistic distribution with scale parameter. (from Gnumeric) + +Arguments +X: a free value +Scale: a number >= 0 + + + + + +Pareto Distribution + +pareto(X, Exponent, Scale) +Returns the probability density p(x) at x for a Pareto distribution with exponent and scale. (from Gnumeric) + +Arguments +X: a free value +Exponent: a number >= 0 +Scale: a number >= 0 + + + + + +Rayleigh Distribution + +rayleigh(X, Sigma) +Returns the probability density p(x) at x for a Rayleigh distribution with scale parameter sigma. (from Gnumeric) + +Arguments +X: a free value +Sigma: a number >= 0 + + + + + +Rayleigh Tail Distribution + +rayleightail(X, Lower limit, Sigma) +Returns the probability density p(x) at x for a Rayleigh tail distribution with scale parameter sigma and a lower limit. (from Gnumeric) + +Arguments +X: a free value +Lower limit: a free value +Sigma: a number >= 0 + + + + + + + +Means + + +Geometric Mean + +geomean(Data) + +Arguments +Data: a vector + + + + + +Harmonic Mean + +harmmean(Data) + +Arguments +Data: a vector + + + + + +Mean + +mean(Data) +average +Arguments +Data: a vector + + + + + +Quadratic Mean (RMS) + +rms(Data) + +Arguments +Data: a vector + + + + + +Trimmed Mean + +trimmean(Data, Trimmed percentage (at each end)) + +Arguments +Data: a vector +Trimmed percentage (at each end): a free value + + + + + +Weighted Mean + +weighmean(Data, Weights) + +Arguments +Data: a vector +Weights: a vector + + + + + +Winsorized Mean + +winsormean(Data, Winsorized percentage (at each end)) + +Arguments +Data: a vector +Winsorized percentage (at each end): a free value + + + + + + + +Moments + + +Covariance + +cov(Data 1, Data 2) +covar +Arguments +Data 1: a vector +Data 2: a vector + + + + + +Mean Deviation + +meandev(Data) + +Arguments +Data: a vector + + + + + +Pooled Variance + +poolvar(Data 1, Data 2) + +Arguments +Data 1: a vector +Data 2: a vector + + + + + +Standard Deviation (entire population) + +stdevp(Data) + +Arguments +Data: a vector + + + + + +Standard Deviation (random sampling) + +stdev(Data) + +Arguments +Data: a vector + + + + + +Standard Error + +stderr(Data) + +Arguments +Data: a vector + + + + + +Variance (entire population) + +varp(Data) + +Arguments +Data: a vector + + + + + +Variance (random sampling) + +var(Data) + +Arguments +Data: a vector + + + + + + + +Regression + + +Pearson's Correlation Coefficient + +pearson(Data 1, Data 2) +correl +Arguments +Data 1: a vector +Data 2: a vector + + + +Requirement +dimension("Data 1")=dimension("Data 2") + + + + + +Spearman's Rho + +spearman(Data 1, Data 2) + +Arguments +Data 1: a vector +Data 2: a vector + + + +Requirement +dimension("Data 1")=dimension("Data 2") + + + + + +Statistical Correlation + +cor(Data 1, Data 2) + +Arguments +Data 1: a vector +Data 2: a vector + + + + + + + +Statistical Tests + + +Paired T-Test + +pttest(Data 1, Data 2) + +Arguments +Data 1: a vector +Data 2: a vector + + + + + +Unpaired T-Test + +ttest(Data 1, Data 2) + +Arguments +Data 1: a vector +Data 2: a vector + + + + + + + + +Step Functions + + +Heaviside Step Function + +heaviside(Value) +Discontinuous function also known as "unit step function". Returns 0 if x < 0, 1 if x > 0, and 1/2 if x = 0. + +Arguments +Value: a real number + + + + + +Logit Transformation + +logit(Value) + +Arguments +Value: a number + + + + + +Ramp Function + +ramp(Value) + +Arguments +Value: a real number + + + + + +Rectangular Function + +rectangular(Value) + +Arguments +Value: a real number + + + + + +Sigmoid Function + +sigmoid(Value) + +Arguments +Value: a number + + + + + +Triangular Function + +triangular(Value) + +Arguments +Value: a real number + + + + + + + +Trigonometry + + +Cosecant + +csc(Angle) + +Arguments +Angle: an angle or a number (using the default angle unit) + + + + + +Cosine + +cos(Angle) + +Arguments +Angle: an angle or a number (using the default angle unit) + + + + + +Cotangent + +cot(Angle) + +Arguments +Angle: an angle or a number (using the default angle unit) + + + + + +Hyperbolic Cosecant + +csch(argument 1) + +Arguments +1: a free value + + + + + +Hyperbolic Cosine + +cosh(argument 1) + +Arguments +1: a number + + + + + +Hyperbolic Cotangent + +coth(argument 1) + +Arguments +1: a free value + + + + + +Hyperbolic Secant + +sech(argument 1) + +Arguments +1: a free value + + + + + +Hyperbolic Sine + +sinh(argument 1) + +Arguments +1: a number + + + + + +Hyperbolic Tangent + +tanh(argument 1) + +Arguments +1: a free value + + + + + +Inverse Cosecant + +acsc(argument 1) + +Arguments +1: a free value + + + + + +Inverse Cosine + +acos(argument 1) + +Arguments +1: a number + + + + + +Inverse Cotangent + +acot(argument 1) + +Arguments +1: a free value + + + + + +Inverse Hyperbolic Cosecant + +acsch(argument 1) + +Arguments +1: a free value + + + + + +Inverse Hyperbolic Cosine + +acosh(argument 1) + +Arguments +1: a number + + + + + +Inverse Hyperbolic Cotangent + +acoth(argument 1) + +Arguments +1: a free value + + + + + +Inverse Hyperbolic Secant + +asech(argument 1) + +Arguments +1: a free value + + + + + +Inverse Hyperbolic Sine + +asinh(argument 1) + +Arguments +1: a number + + + + + +Inverse Hyperbolic Tangent + +atanh(argument 1) + +Arguments +1: a number + + + + + +Inverse Secant + +asec(argument 1) + +Arguments +1: a free value + + + + + +Inverse Sine + +asin(argument 1) + +Arguments +1: a number + + + + + +Inverse Tangent + +atan(argument 1) + +Arguments +1: a number + + + + + +Radians to Default Angle Unit + +radtodef(Radians) + +Arguments +Radians: a free value + + + + + +Secant + +sec(Angle) + +Arguments +Angle: an angle or a number (using the default angle unit) + + + + + +Sine + +sin(Angle) + +Arguments +Angle: an angle or a number (using the default angle unit) + + + + + +Tangent + +tan(Angle) + +Arguments +Angle: an angle or a number (using the default angle unit) + + + + + + + +Utilities + + +ASCII Char + +char(Value) + +Arguments +Value: an integer >= 32 and <= 127 + + + + + +ASCII Value + +code(Character) + +Arguments +Character: a text string that fulfills the condition: "len(\x) = 1" + + + + + +Concatenate Strings + +concatenate(Text string 1[, Text string 2], ...) + +Arguments +Text string 1: a text string +Text string 2: a text string (optional) + + + + + +Custom Sum of Elements + +csum(First element, Last element, Initial value, Function, Value variable, Element variable, Vector[, Index variable][, Vector variable]) + +Arguments +First element: an integer +Last element: an integer +Initial value: a free value +Function: a free value +Value variable: an unknown variable/symbol +Element variable: an unknown variable/symbol +Vector: a vector +Index variable: an unknown variable/symbol (optional, default: "") +Vector variable: an unknown variable/symbol (optional, default: "") + + + + + +Display Error + +error(Message) + +Arguments +Message: a text string + + + + + +Display Message + +message(Message) + +Arguments +Message: a text string + + + + + +Display Warning + +warning(Message) + +Arguments +Message: a text string + + + + + +Function + +function(Expression, Arguments) + +Arguments +Expression: a text string +Arguments: a vector + + + + + +Length of string + +len(Text) + +Arguments +Text: a text string + + + + + +Process Matrix Elements + +processm(Function, Element variable, Matrix[, Row variable][, Column variable][, Matrix variable]) + +Arguments +Function: a free value +Element variable: an unknown variable/symbol +Matrix: a matrix +Row variable: an unknown variable/symbol (optional, default: "") +Column variable: an unknown variable/symbol (optional, default: "") +Matrix variable: an unknown variable/symbol (optional, default: "") + + + + + +Process Vector Elements + +process(Function, Element variable, Vector[, Index variable][, Vector variable]) + +Arguments +Function: a free value +Element variable: an unknown variable/symbol +Vector: a vector +Index variable: an unknown variable/symbol (optional, default: "") +Vector variable: an unknown variable/symbol (optional, default: "") + + + + + +RPN Stack Register + +register(Index) +Returns the value of a RPN stack register. + +Arguments +Index: an integer >= 1 + + + + + +RPN Stack Vector + +stack() +Returns the RPN stack as a vector. + + + +Replace + +replace(Expression, Original value, New value[, Precalculate expression]) +Replaces a certain value in an expression with a new value. The expression is calculated before the replacement if the fourth argument is true. + +Arguments +Expression: a free value +Original value: a free value +New value: a free value +Precalculate expression: a boolean (0 or 1) (optional, default: 0) + + + + + +Save as Variable + +save(Value, Name[, Category][, Title]) + +Arguments +Value: a free value +Name: a text string +Category: a text string (optional, default: Temporary) +Title: a text string (optional) + + + + + +Select Vector Elements + +select(Vector, Condition[, Element variable][, Select first match]) + +Arguments +Vector: a free value +Condition: a free value +Element variable: an unknown variable/symbol (optional, default: x) +Select first match: a boolean (0 or 1) (optional, default: 0) + + + + + +Strip Units + +nounit(Expression) +strip_unitsRemoves all units from an expression. The expression is calculated before the removal. + +Arguments +Expression: a free value + + + + + +Title + +title(Name) + +Arguments +Name: a valid function, unit or variable name + + + + + + + diff --git a/doc/en/qalculate_kde/gnuplot.png b/doc/en/qalculate_kde/gnuplot.png new file mode 100644 index 0000000000000000000000000000000000000000..59df8e7b76b7556d19a2756ffb8453c200b6b197 GIT binary patch literal 14468 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 z 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 literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/index.docbook b/doc/en/qalculate_kde/index.docbook new file mode 100644 index 0000000..36d492c --- /dev/null +++ b/doc/en/qalculate_kde/index.docbook @@ -0,0 +1,1528 @@ + +Qalculate! 0.9.7"> + + + + + + + +]> + + + + +The &qalculate_kde; Handbook + + + + + +Niklas Knutsson + +

nq@altern.org
+ + + + + + + +2005 +Niklas Knutsson + + + +&FDLNotice; + + + +2007-05-25 +0.9.7 + + + +&qalculate_kde; is a multi-purpose desktop calculator for GNU/Linux. +It is small and simple to use but with much power and versatility underneath. +Features include customizable functions, units, arbitrary precision, plotting, and a user-friendly +interface. + + + + +KDE +qalculate-kde +calculator +math + + + + + +Introduction + +Qalculate! is not your regular software replication of the cheapest available calculator. Qalculate! aims to make full use of the superior interface, power and flexibility of modern computers. + + +The center of attention in Qalculate! is the expression entry, Instead of entering each number in a mathematical expression separately, you can directly write the whole expression and later modify it. Just enter an expression as you would write it on paper, press Enter and voila! + + +The interpretation of expressions is flexible and fault tolerant, and if you nevertheless do something wrong, Qalculate! will tell you so. Not fully solvable expressions are however not errors. Qalculate! will simplify as far as it can and answer with an expression. + + +In addition to numbers and arithmetic operators, an expression may contain any combination of variables, units, and functions. These are immediately accessible from the user interface — the menu bar, the managers, the calculator keypad, and automatic completion. + + +Qalculate! also has some special tools to increase your efficiency, including a number base conversion dialog and a simple plotting interface. + + +Although use of Qalculate! for simple calculations should be natural and self-explanatory, reading the rest of the manual can help you maximize your productivity and discover some maybe unexpected features. More advanced users should read on and discover a large number of customization options and the ability to create and modify your own variables, functions and units directly from the user interface. + + + + +User Interface + +Main Window +
+ Main Window + + + + + + + +
+ +The main window provides a menu bar, the expression entry, the result display and a calculator keypad or history view which can be shown/hidden by clicking on Keypad and History, respectively. There are three buttons to the right of the expression entry and the result display. The upper button performs calculation of the entered expression (same as Enter), the one below saves the current result as a variable (see ), while the last button opens a dialog for conversion of units in the result (see ). When non-default options for the interpretion of expressions have been selected, the choice will be indicated in a small status area below the expression entry, to the right. + +
+ +Expression Entry + +The expression entry is the most important part of the Qalculate! user interface. The normal calculation procedure in Qalculate! is to type in a mathematical expression (ex. 5+5) and press Enter (or click Execute). The result (10) is then displayed below the expression entry in the result display. + +
+ Completion + + + + + + + +
+ +Qalculate! helps out with the expression by giving a list of possible endings to words representing functions, variables and units. The list will narrow with each letter typed. Select an item in the list and the name will be completed. If a function was selected, parenthesis will be added and the position moved for immediate entry of arguments. + + +As the expression is typed in, the area directly direclty below the expression entry, to the left, will show useful information. By default the calculator's interpretation of the expression is shown (ex. 5 * meter for 5m). The interpretation will be displayed in red (configurable) if there are errors in the expression or in blue for lesser errors (for example too many arguments in a function). If the last typed in text represents a function, and arguments are about to be entered, the functions name and its arguments will be displayed. The first argument in the information text is highlighted and includes information about its type and restrictions and when an argument has been entered, the next will be highlighted. + + +After execution of an expression, the whole expression will be marked. This normally means that if something new is entered, the old expression will be overwritten. If, however, an operator (+, −, *, /, ^) is entered first, the old expression will instead be the target of action. The operator will then apply to the whole expression, which is put in parenthesis. This works on all marked ranges, meaning that this way an expression can conveniently be put in parenthesis. Functions set the selection as their first argument. + + +The Up and Down keys will access previously entered expressions. With focus in the expression entry, Up traverses backwards in the expression history and Down forward. + + +The font used for the expression entry can be selected in the preferences dialog (EditConfigure Qalculate!). + +
+ +Result Display + +The result of calculations is displayed in the open area below the expression entry. The font used for the result display can be selected in the preferences dialog (EditConfigure Qalculate!). Use of Unicode signs can be turned off in the same dialog. Otherwise Qalculate! will try to make the result as fancy as possible and print π for pi, √ for sqrt, € for euro, and so on. Information about customization of the mathematical result output is available in . + + +In front of the result an equals or approximately equals sign is shown. This indicates whether Qalculate! was able to calculate/display the result exact or only approximate, in the current mode. + + +The result display has a context menu, which pops up when clicking with the right mouse button anywhere in the field. This menu provides a subset of the display alternatives from the mode menu () and some actions from the edit menu (). See more info in . Show Parsed Expression shows how the entered expression was interpreted before the calculation leading to the current result. + + +When you move the mouse over parts of the result, descriptions will pop up for variables, functions and units. This will only work if you have tooltips enabled in KDE. You can also show this information by double clicking or selecting Show Object Info in the context menu. For matrices and vectors, this will open a window with a spreadsheet-like table displaying the contents of the matrix/vector. + + +To copy the result, either select EditCopy Result, or mark and copy the text from the result display or history. Note that all results are not displayed in the result display as an expression which can be used directly in the expression entry. This is true for divisions, powers and vectors. For example, when the result "x^5" is marked and copied, the power sign will be lost. + + + +Keypad + +The keypad provides access to a fairly small set of traditional calculator buttons, which work as expected. The top buttons (from left to right) toggles exact calculation, toggles fractional number display, selects display mode and selects number base in result (see ). +
+ Keypad + + + + + + + +
+
+
+ +Calculation History + +The history view provides access to previous calculation results (50 rows are reloaded on restart). Previous expressions and results, as well as errors and warnings, are displayed in plain text and can be marked and copied (from the right-button context menu or with CtrlC) to the expression entry or elsewhere. +
+ Calculation History + + + + + + + +
+ +
+
+ +Menu Bar + +The menus in the menu bar provides access to most of the functionality of Qalculate!. Their contents are listed and described below. + + + File Menu + + + + + + Menu Item + Description + + + + + New + Submenu for creation of new objects. See . + + + Import CSV File... + Opens a dialog for import of a data file as a matrix or vectors. + + + Export CSV File... + Opens a dialog for export of a matrix or vector to a data file. + + + Store Result... (CtrlS) + Stores the current result as a variable. See . + + + Save Result Image... + Saves the result display to a PNG image. + + + Save Definitions + Saves all user definitions (variables, functions and units). + + + Update Exchange Rates + Downloads current exchange rates from the Internet. + + + Plot Functions/Data + Opens the plot dialog. See . + + + Convert Number Bases + Opens the number bases converter. See + + + Periodic Table + Shows a periodic table, with property values which can be inserted in the expression, in a new window. + + + Quit (CtrlQ) + Exits Qalculate! + + + +
+ + New Menu + + + + + + Menu Item + Description + + + + + Variable + Opens the variable edit dialog for creation of a new variable. + + + Matrix + Opens a dialog for entry of a new matrix variable. + + + Vector + Opens a dialog for entry of a new vector variable. + + + Unknown Variable + Opens the variable edit dialog for creation of a new unknown variable. + + + Function + Opens the function edit dialog for creation of a new function. + + + Data Set + Opens the data set edit dialog for creation of a new data set. + + + Unit + Opens the unit edit dialog for creation of a new unit. + + + +
+ + Edit Menu + + + + + + Menu Item + Description + + + + + Manage Variables (F2) + Opens the variable manager. See . + + + Manage Functions (F3) + Opens the function manager. See . + + + Manage Units (F4) + Opens the unit manager. See . + + + Manage Data Sets + Opens the data set manager. + + + Factorize + Factorizes the current result. For multivariate rational polynomials, only square free factorization is supported. + + + Simplify + Simplifies the current result. Note that easy simplifications are always automatically performed. + + + Set Unknowns... + Opens a dialog where the values of unknown variables in the result can be set and the result recalculated. + + + Convert To Unit + Submenu with units. Select a unit to convert the current result. + + + Set Prefix + Submenu for choice of unit prefix in current result. + + + Convert To Unit Expression (CtrlT) + Opens the convert to unit dialog for conversion of result to custom unit expression. See . + + + Convert To Base Units + Splits up unit(s) in the current result into base units. + + + Convert To Best Unit + Tries to convert the units in the current result so that as few units as possible is used. Base units are prioritized. + + + Insert Matrix + Opens a dialog where you can create a matrix in a spreadsheet-like table and insert into the expression entry. If selected expression text is a matrix, then the matrix is edited. + + + Insert Vector + Opens a dialog where you can create a vector in a spreadsheet-like table and insert into the expression entry. If selected expression text is a vector, then the vector is edited. + + + Copy Result (F5) + Copies the current result to the clipboard. + + + Configure Qalculate! + Opens the preferences dialog, which controls settings for visual appearance and start/exit actions. + + + Configure Shortcuts... + Opens a dialog for configuring keyboard shortcuts. + + + +
+ + Mode Menu + + + + + + Menu Item + Description + + + + + Number Base + Submenu with a list of number bases (binary, octal, decimal, hexadecimal, sexagesimal, time format, and other bases, and roman numerals) to select for result display, and a menu item (CtrlB) for opening a dialog to switch number bases in expression (input) and result (output). + + + Numerical Display + Submenu which selects numerical display mode. See . + + + Fractional Display + Submenu which selects decimal, fractional or combined fractional display. See . + + + Unit Display + Submenu which controls the display of units and prefixes. See . + + + Angle Unit + Submenu which sets the default angle unit for trigonometric functions. + + + Abbreviate Names + Toggles on/off use of abbreviation for unit, prefix, variable and function names in result display. + + + Enabled Objects + Submenu which enables/disables variables, functions, units and unknowns (will not affect defined unknown variables and quoted unknowns), and calculation of variables (If calculation of variables is not on, all variables will be treated as unknown). Here you can also disable complex and infinite results. + + + Approximation + Submenu which switches between different approximation modes. + + + Assumptions + Submenu which changes default assumptions for unknown variables. + + + Algebraic Mode + Submenu with options to automatically simplify or factorize the final result. Note that even if this is set to none, easy simplifications will be performed. In this menu, the option toggle on/off use of the assumption that unknown denominators not are zero is also found. This alternative makes it possible to avoid the situation where expressions such as (x-1)/(x-1) can not be further simplified because the denominator might be zero (if x equals 1). + + + Read Precision + Enables/disables interpretation of input numbers with decimals as approximate with a precision equal to the number of digits (after preceding zeroes). + + + Limit Implicit Multiplication + Activates/deactivates limits to implicit multiplication when parsing and displaying expressions. For details see + + + RPN Mode (CtrlR) + Toggles Reverse Polish Notation mode on/off. For details see + + + RPN Syntax + Toggles use of Reverse Polish Notation syntax in expressions on/off. + + + Precision + Opens a dialog to change precision in calculations. + + + Decimals + Opens a dialog to change displayed number of decimals. + + + Meta Modes + Provides a list of available meta modes for loading and menu items to save and delete modes. + + + Save Default Mode + Saves the current calculator mode as the startup default. + + + +
+ + Functions Menu + + + + + + Menu Item + Description + + + + + (Recent functions list) + Select a function to open the insert function dialog. + + + (Function list) + Select a function to open the insert function dialog. + + + +
+ + Variables Menu + + + + + + Menu Item + Description + + + + + (Recent variables list) + Select a variable to insert it into the expression entry. + + + (Variable list) + Select a variable to insert it into the expression entry. + + + +
+ + Units Menu + + + + + + Menu Item + Description + + + + + (Recent units list) + Select a unit to insert it into the expression entry. + + + (Unit list) + Select a unit to insert it into the expression entry. + + + +
+ + Help Menu + + + + + + Menu Item + Description + + + + + Qalculate! Handbook(F1) + Invokes the KDE Help system starting at the Qalculate! help pages. (this document). + + + What's This?(ShiftF1) + Changes the mouse cursor to a combination arrow and question mark. Clicking on items within Qalculate! will open a help window (if one exists for the particular item) explaining the item's function. + + + About Qalculate! + This will display version and author information. + + + About KDE + This displays the KDE version and other basic information. + + + +
+ +
+ +Variable/Function/Unit Managers + +The manager windows provide a structural way of working with variables, functions and units (collectively referred to as objects). The managers for the three different objects are essentially similar. They can be opened from the edit menu. F2, F3 and F4 can also be used for variables, functions and units respectively. The function manager can also be opened with the f(x) button in the keypad. + +
+ Variable Manager + + + + + + + +
+ +To the left is a category tree and beside that is a list of all objects in the selected category, including all subcategories. Objects without a category are put under Uncategorized. The top category, All, provides a list of all objects, except those that are deactivated and available in the second top-level category — Inactive. The object list does, in addition to descriptive names, for variables have an extra column for values of variables, and units have additional columns for abbreviation/singular/plural and base unit. + + +The buttons on the right work on the selected object in the list. New opens a dialog for creation of a new object, while Edit opens the same dialog to edit the selected unit. Insert inserts the object into the expression entry in the main window, Delete removes the object and (De)activate toggles recognition in expressions on/off. The unit manager has an additional button for conversion of the current result and the variable manager a button for export to a data file. + +
+ Function Manager + + + + + + + +
+ +The function manager has a description box at the bottom, which shows the syntax, description and arguments of the selected function. + +
+ Unit Manager + + + + + + + +
+ +The unit manager has an area for quick conversion between units. This converts between the selected unit in the list and the selected unit in the option menu. The menu contains the same units that are available in the list. Units are converted by specification of a quantity, in the entry next to the unit to convert from, followed by Enter. + + +For more information about variables, functions and units, see , and . + +
+ +Convert Number Bases Dialog + +The number bases dialog, accessible from the File Menu, is an efficient and convenient tool for conversion between binary, octal, decimal and hexadecimal numbers. This dialog contains entries for each number base. When a number is typed in any of the entries, the others are automatically updated to display the current number in their format. Numbers, or expressions, entered follow the same rules as expressions in the main expression entry. +
+ Convert Number Bases Dialog + + + + + + + +
+
+
+
+ + +Expressions + +Expressions are mathematical statements. Mathematical questions are asked through expressions, which contains objects tied together with operators. The result of an expression may also be an expression, if the result is not a single object. Apples and oranges can be mixed, but the result will hold them apart. Qalculate! knows algebra. + + +Objects + +In Qalculate! mathematical entities, such as numbers and variables, are referred to as objects. The recognized object types are listed below. + + + + + Numbers + + These are the regular numbers composed by digits 0-9 and a decimal sign — a dot, or a comma if it is the default decimal point in the locale/language used. If comma is used as decimal sign, the dot is still kept as an alternative decimal sign, if not explicitely turned off in the preferences dialog with Ignore dots in number (to allow it to be used as thousand separator instead). Numbers include integers, real numbers, and complex numbers. The imaginary part of complex numbers are written with as regular number followed by the special variable i, which represents the square root of -1 (ex. 2 + 3i). Spaces between digits are ignored (5 5 = 55). E (or e) can be considered as a shortcut for writing many zeroes and is equivalent to multiplication by 10 raised to the power of the right-hand value (ex. 5E3 = 5000). + Sexagesimal numbers (and time) can be entered directly using colons (ex. 5:30 = 5.5). A number immediately preceeded 0b, 0o or 0x are interpreted as a number with base 2, 8 or 16, respectively (if the default base is 10, ex. 0x3f = 63). The number base in can also be selected, either by using the base(), bin(), oct(), hex() and roman() functions, or by setting the base used for all numbers in the whole expression from ModeNumber BaseSelect Result and Expression Base.... + + + + Vectors and Matrices + + A matrix is a two-dimensional rectangular array of mathematical objects. Vectors are matrices with only one row or column, thus one-dimensional sequences of objects, Vectors and matrices are generated by vector(), matrix() and similar functions, or stored in a variable. Syntax in the form of [1, 2, 3, 4] and [[1, 2], [3, 4]] can also be used. + + + + Variables/Constants + + See . + + + + Functions + + See . + + + + Units and Prefixes + + Qalculate! understands abbreviated, plural and singular forms of unit names and prefixes. Prefixes must be put immediately before the unit to be interpreted as prefixes — 5 mm = 0.005 m, but 5 m m = 5 m^2. Also, for convenience units allow the power operator to be left out. A number following immediately after a unit is interpreted as an exponent (ex. 5 m2 = 5 m^2). This does not apply to currencies, as they might be put in front of the quantity. More information in . + + + + Unknowns + + Unknowns are text strings without any associated value. If Qalculate! finds a character that are not associated with any variable, function or unit in an expression, then it will be regarded as an unknown variable. These are temporary unknown variables with default assumptions. Unknowns can also be explicitly entered by putting a text string in quotes. This is also necessary for undefined unknown variables with more than one character (ex.xy is just one object, while xy means x * y). See . + + + + Text + + This category represent a number of different function argument types, such as regular text, dates and file names. They can, but do not need to be put in quotes except when containing the argument separator (, or ;). + + + + + +To avoid confusion, functions, units, variables and unknown variables can independently be disabled. + + +Variables, functions and units are all accessible in the menus and in the variable, function and unit managers, If their names are not remembered. Functions accessed this way has some extra conveniences. If the function has at least one argument, a dialog will pop up where arguments can be entered and a description of the +function and its arguments is available. + + +Qalculate! can handle most commonly used symbols for certain variables, functions and units, even though most are difficult to find on a keyboard. These include π for pi, √ for sqrt, € for euro, and so on. Most importantly it is possible to copy these symbols when used in the result. + + +For more information about variables, functions and units, see , and . + + + +Operators + +The following operators are defined in Qalculate! and may be used in expressions. + + + Operators + + + + + + + + + Operation + Symbol + Description + Example + Result + + + + + Addition + + + Adds the right value to the left value. + 1 + 1 + 2 + + + Subtraction + + Subtracts the right value from the left value. + 1 − 1 + 0 + + + Multiplication + ⋅ or * + Multiplies the left value by the right value. + 2 * 2 + 4 + + + Division + / + Divides the left value by the right value. + 2 / 2 + 1 + + + Exponent + ^ + Raises the left value by the right value. Can also be typed as **. Note that x^y^z equals x^(y^z), and not (x^y)^z. + 2^3 + 8 + + + 10^x + E + Multiplies the left value with 10 raised to the power of the right value. Equivalent to the exponential number format in result display. E is as much an operator as part of numbers. + 1E3 + 1000 + + + Parenthesis + ( and ) + Evaluates the expression in parenthesis first. + 5 * (1 + 1) + 10 + + + Less than + < + Returns 1 for true, if the left value is is less than the right, and 0 for false. + 1 < 2 + 1 + + + Greater than + > + Returns 1 for true, if the left value is greater than the right, and 0 for false. + 1 >2 + 0 + + + Less than or equal + ≤ or <= + Returns 1 for true, if the left value is less than or equal the right, and 0 for false. + 1 <= 2 + 1 + + + Greater than or equal + ≥ or >= + Returns 1 for true, if the left value is greater than or equal the right, and 0 for false. + 1 >= 2 + 0 + + + Equals + = + Returns 1 for true, if the left value equals the right, and 0 for false. + 1 = 2 + 0 + + + Not equals + ≠ or != + Returns 1 for true, if the left value not equals the right, and 0 for false. + 1 != 2 + 1 + + + Logical NOT + ! + Returns 1 for true, if the value to the right is false, and 0 for false. + !(1>2) + 1 + + + Logical OR + || or OR + Returns 1 for true, if the right or left value is true, and 0 for false. + 1>2 || 2>1 + 1 + + + Logical AND + && or AND + Returns 1 for true, if the right and left value is true, and 0 for false. + 1>2 && 2>1 + 0 + + + Bitwise NOT + ~ + Equivalent to -1-x. + ~(0010 | 1100) + -1111 + + + Bitwise Shift Left + << + Shifts the bits of the left value x steps to the left, where x is the value on the right. Implemented as a shortcut for shift() + 0011 << 1 + 0110 + + + Bitwise Shift Right + >> + Shifts the bits of the left value x steps to the right, where x is the value on the right. Implemented as a shortcut for shift() + 0011 << 1 + 0001 + + + Bitwise OR + | + If a bit is 1 in one of the numbers set it to 1, otherwise 0. Also functions as elementwise logical operator on vectors. + 0010 | 1100 + 1110 + + + Bitwise AND + & + If a bit is 1 in both numbers set it to 1, otherwise 0. Also functions as elementwise logical operator on vectors. + 1010 & 0011 + 0010 + + + +
+ +The operator names plus, minus, times, per, AND and OR may also be used, surrounded by space, for the corresponding operation (ex. 5 plus 2, but not 5plus2, equals 5 + 2). +These operator names are localized, but AND and OR are always available. +In addition to these operators there are a couple of shortcuts for certain functions, such as 5! which equals factorial(5). + + +The multiplication sign can generally be left out. This is not true for numbers (5(5) = 25 but 5 5 = 55). Expressions can also generally be written with or without spaces with the same result (2xsin(2) equals 2 x sin(2) which equals 2*x*sin(2)), but be careful. The vast number of functions and units means that without separating spaces, the result might not be obvious. To avoid confusion Qalculate! can limit the use of implicit multiplication (ModeLimit Implicit Multiplication), so that space, operator or parenthesis must be put between functions, units and variables (in this mode esqrt(5) does not equal e * sqrt(5)). Also note that unit prefixes must be put immediately before the unit, to be interpreted as prefixes (5 mm = 0.005 m, but 5 m m = 5m^2). You can see how to expression was interpreted in the history window. + + +Usually, mathematical expressions are written as normally expected. Standard operator precedence apply. Expressions are evaluated according to the following priorities: + + Parenthesis + E (10^x) + Short multiplication in front of variables, units, functions, parenthesis etc. (ex. 5(2+3)). Note that this implies that 2/5 cm equals 2/(5 cm) and not (2/5) cm + Functions (ex. sqrt(2)) + Exponents (x^y) + Multiplication and division (*, /) + Addition and subtraction (+, −) + Bitwise NOT (~) + << and >> + Bitwise AND (&) + Bitwise OR (|) + Comparison (>, <, =, >=, <=) + Logical NOT (!) + Logical AND (&&) + Logical OR (||) + + + + +
+
+ + +Calculator Modes + +Qalculate! provides flexible parsing, calculation output and result display. There are several ways in which parsing of expression and display of results can be customized. These modes can generally be changed through the mode menu. The state of each mode can be saved under a name in ModeMeta Modes for quick access. The Preset and Default meta modes are always available and represents the state when Qalculate! is load for the first time and the mode settings automatically loaded at each startup (and by default saved on exit), respectively. Different modes are summarized below. + + +Number Bases + +Non-decimal bases can be selected for display of numbers in the result. This include regular number bases (binary, octal, hexadecimal, sexagesimal) as well as sexagesimal time format and roman numerals. All number bases between 2 and 36, and base for expression input, can be selected from a dialog window accessed from ModeNumber BaseOther... or ModeNumber BaseSelect Result and Expression Base.... The convert number bases dialog (see ) is efficient for simple conversion between common bases. + + + +Numerical Display + +These modes mainly control when numbers are displayed exponentially (ex. 2.62E3 which equals 2620). In the default normal mode, numbers are displayed in exponential format if the exponent will be greater than the current precision. In scientific mode the lowest exponent is 3. In simple numerical mode the exponential format is never used and it is always used in purely scientific mode. In the engineering mode, the exponent is always a multiple of three. This is naturally equivalently true for numbers less than one and negative exponents. When the scientific modes are selected in the keypad (not from the menubar), negative exponents are automatically activated and sort minus last deactivated, while normal and simple modes do the opposite. + + + +Indicate Infinite Series + +If this option is on, Qalculate! will not round infinitely repeating digit sequences if discovered. Instead ... will be displayed after the maximal number of decimals and the result indicated as exact (compare 2/3 = 0.666667 with 2/3 = 0.666666...). + + + +Round Halfway Number To Even + +With this option, halfway numbers will be rounded to even instead of upwards (ex. 2.65 is then rounded to 2.6 instead of 2.7). Note that this behavior is always applied in the round() function. + + + +Show Ending Zeroes + +if this option is on, approximate numbers in the result will be appended with zeroes, so that the number of digits (after preceding zeroes) will equal the precision. + + + +Negative Exponents + +If negative exponents is activated, division is shown as a negative power (ex. x * y^-1 instead of x / y). + + + +Sort Minus Last + +This option decides if minus signs should be avoided in the first positions of the result expression. + + + +Fractional Display + +This controls if numbers are displayed in fractional or decimal mode. Decimal mode displays numbers as usually expected (6/4 = 1.5), combined displays a whole number and a fraction (6/4 = 1 1/2) and fractional only displays as fraction (6/4 = 3/2). + + + +Unit Display + +The use of prefixes for units can be toggled on and off. By default prefixes representing a power of ten not dividable by three (centi, deci, deca and hekto) are not used and need to be enabled. If denominator prefixes are not explicitly enabled, prefixes will only be set for the numerator in a fractional unit expression (ex. 1 Mg/m or 1 kg/mm). The place units separately alternative controls the display of unit expressions in result. If it is enabled (default) units will be displayed separate from other parts of the expression at the end (compare (5x*m)/(y*s) and 5x/y m/s). + + + +Abbreviate Names + +The display of unit, prefix, variable and function names can be controlled by selecting to display abbreviations or full length names (ex. 5 cm or 5 centimeters). Both abbreviations and long names can however always be entered in expressions. + + + +Approximation + +When always exact mode is on, the calculation will not go further than what can be calculated exactly (ex. sqrt(2+3) = sqrt(5)). The default Try Exact mode, will calculate the result exact as far as possible and then approximately. Approximate mode will directly calculate a approximate result, thus being a bit faster but giving a less correct approximate indication (sin(pi/2) return approximately one instead of exactly one). + + + +Assumptions + +This controls the default assumptions for unknown variables without explicitly defined assumptions. See . +The assume denominators non-zero alternative makes it possible to avoid the situation where expressions such as (x-1)/(x-1) can not be further simplified because the denominator might be zero (if x equals 1). With this alternative activated the example can be reduced to 1. + + + +Precision + +Precision controls the precision in approximate numbers and the number of significant digits. If the read precision option is turned on, input numbers with decimals will be interpreted as approximate with a precision equal to the number of digits (ex. 2.50 + 3.4567 = 5.96). + + + +Decimals + +In the decimals dialog, the number of decimals displayed can be controlled. This includes minimal (will fill out with zeroes) and maximal number of decimals (will round numbers). + + + +Limit Implicit Multiplication + +If the limit implicit multiplication mode is activated, the use of implicite multiplication when parsing expressions and displaying results will be limited to avoid confusion. For example, if this mode is not activated and integrte(5x) is accidently typed instead of integrate(5x), the expression is interpreted as int(e * e * (5 * x) * gr * t) (displayed in history window). The result will then without any error be int(2.3940139x * km^2) instead of 2.5x^2. If limit implicit multiplication is turned on to mistyped expression would instead show an error telling that integrte is not a valid variable, function or unit (unless unknowns is not enabled in which case the result will be 5 "integrate" * x). When implicit multiplication is limited variables, functions and units must be separated by a space, opertor or parenthesis (xy does not equal x * y). + + + + + +The RPN Mode + +The Reverse Polish Notation mode can be activated with ModeRPN Mode, CtrlR or from the context menu of the expression entry. For details about what Reverse Polish Notation is and how it generally works, see for example the RPN article at Wikipedia. + + +Central to the RPN mode is the stack, a list of registers/values that is operated on by functions and operators. The stack has a variable number of registers which can hold an unlimited number of values. The stack size is dynamically changed when a new value is added and the first value on the stack is shown in the result display. Mathematical operators such as plus and minus then operates on the first two, last added, values on the stack. The second value is changed with input from the first value. For example, the minus operator subtracts the first value from the second. Functions which require exactly one argument operates on the first value on the stack. Other functions, which require multiple arguments, must be entered in normal expression based way. + + +The RPN mode still allows full expression to be entered (you can add 5x+3+23+sin(2) directly to the stack). The buttons on the keypad do not insert operators and functions in the expression entry, but instead applies them to the stack. This is also true for the keypad keys on the keyboard. Enter calculates the current expressions and adds it to the stack. If the expression entry is not empty when applying an operator or function to the stack, the expression is first calculated and added to the stack. All keys on the main part of the keyboard add the corresponding characters in expression entry, unless the Use only keypad keys for RPN option is deactivated from the preferences dialog. To apply the raise operator '^' to the stack, without clicking the keypad button with the mouse, use the Ctrl* (keypad) shortcut. If the expression only contains an operator or a function, which requires exactly one argument, the operator/function is applied to the stack. + + +For example, 5 ENTER 3 + 2 / adds 5 to the stack, then adds 3 to the stack and moves 5 down a step and adds 3 to 5. The first value, 3, is removed from the stack and the value left is 8. Then 2 is added to the stack and 8 is divided by 2, resulting in 4. This would in a single expression be entered as (5+3)/2. + +
+ RPN Mode + + + + + + + +
+ +The RPN mode adds a third page to the main window, for display and manipulation of the values on the stack. This shows a list of values on the stack, with the last added value on the top. On the right are buttons for moving the selected value up or down, editing or removing the selected value, or remove all values from the stack. The equals buttons do in RPN mode in addition to calculating the expression, add it to the stack. + + +Changes in the display of result only affects the first value on the stack. + + +Note that Qalculate! in addition to the RPN mode, has a RPN syntax. The RPN syntax controls how expressions is interpreted. This means that instead of as with a traditional RPN calculator, where each value and operator is put on the stack separately, all values and operators are entered directly in an expression, with ENTER replaced by space (ex. 5 2 + which corresponds to 5 ENTER 2 ENTER +, and equals 5 + 2 in regular notation). + +
+
+ + +Variables + +Variables are used to conveniently store a fixed value/result under a name. Variables can store everything that a result may contain, including numbers, units, variables, unsolved expressions and functions etc. + + +There two different kinds of variables known and unknown. Known variables represents a fixed value, usually a number, while unknown variables represents a range or type of values (ex. a non-negative integer). + + +Some common constants that can only be approximately represented by a real number, such as pi and e, are special known variables. They are not fixed but are recalculated each time precision changes, thereby not compromising the arbitrary precision of Qalculate!. + + +The ans variable, which always contains the last calculated result, is another special and useful variable. + + +The unknown variables x, y and z are predefined. They cannot be deleted, but changed. By default they use the default assumptions. + + +For a complete list of available variables see or the variable manager. + + +Variable creation/editing +
+ Store Result + + + + + + + +
+ +The easiest way to create a known variable is to store the current result. This can be done by clicking the STO button or selecting FileStore Result.... Type a name for the variable in the dialog that pops up and optionally enter a category and descriptive name to keep variables well organized. + + +Known variables can also be created from scratch by selecting FileNewVariable or by clicking New in the variable manager. The value can then be filled in, in the text field below the name, and specified as exact or approximate. + +
+ New Variable + + + + + + + +
+ +The dialog for creation of unknown variables are accessed by selecting FileNewUnknown Variable. Instead of a value, an assumed type and sign can then be entered. + + +Edit a variable by clicking Edit in the variable manager. + + + +Variables stored in the Temporary category will not be saved after the program exit. + + +
+ +Vectors and Matrices + +Vectors and matrices are most effectively used stored in a variable. Qalculate! provides separate tools for these variables. They use a different dialog, where each element can be edited separately as in a spreadsheet. As with other variables, click Edit in the variable manager to edit a matrix/vector variable, but to create a new, select FileNewMatrix or FileNewVector. + +
+ Matrix/Vector Edit Dialog + + + + + + + +
+ +In this dialog, name, category and descriptive name are typed in as usual, but instead of a single value entry, the matrix/vector edit dialog has a table of entries. Select number of rows and columns above. In a vector this only determines how many value entries that are shown in the table and empty entries will be ignored. For matrices, each entry in the table is an element in the matrix. It is possible to switch between matrix and vector in the dialog (the menu item selected only determines the initial mode). + + + +Matrices and vectors can also be loaded from data files. These files most be plain text files with values organized in separated rows and columns. Select FileImport CSV File... and a dialog window pops up. First select the file to import and then specify whether if it shall be imported as a matrix or vectors. A name, descriptive name and category can optionally be typed in. If the name field is empty, the file name will be used instead. After that, the row in the file where the data starts should be specified. as well as whether this first row contains column headings. Finally the delimiter, used to separate columns in the file, must be selected. Click OK and variables will be generated from the file. If vectors are to be generated and the file contains more than one column, the name will be used as a subcategory and each variable will add the column heading (or Column 1, Column 2, ...) to the name and the descriptive name. + +
+ Import CSV Dialog + + + + + + + +
+ +The load() function can be used to access a CSV file directly in an expression. The reversed action is also available with export(), or the dialog accessed with FileExport CSV File... or from the variable manager. + +
+
+ + +Functions + +Functions are essentially mathematical formulas. They are used to store expressions with variable values, arguments. To execute a function, the values for a number of arguments need to specified. These arguments are then inserted into the expression, making it possible to calculate. + + +Functions is normally entered in an expression by writing the name followed by arguments, separated by commas (or semicolons in languages with comma as decimal point), in parenthesis, thus following the syntax name(arg1, arg2, ...). Qalculate! will give a helpful error message if the arguments are not correct. + +
+ Insert function dialog + + + + + + + +
+ +The insert function dialog presents an easy way to insert a function and its arguments. + + +Although it can lower the readability of an expression, it is perfectly legal to skip the parenthesis and put the arguments after a space, and end with a space or operator. This is most useful in short expressions with single argument functions (ex. sqrt 5). + + +Argument types include: + + Free — anything + Number — a numeric value + Integer — a whole number + Symbol — a defined or undefined unknown variable + Text — a free text string + Date — a date in local or standard format (Year-Month-Day, recommended) + Vector + Matrix + Boolean — 0 for false, 1 for true + Object — the name of a variable, function or unit + Variable — the name of a variable + Function — the name of a function + Unit — the name of a unit + File — the path to a file + Angle — an angle used in trigonometric functions, meaning a number and an angle unit. If no angle unit is included the default is used. + + + +The argument can be restricted by further conditions. For example that a number must be positive. + + +Available Functions + +Here the main function categories and some of their members are described, to give an overview of available functions. For information about separate functions and a complete list of all available functions see or the function manager. + + +Algebra + +Contains sum() and product(), which corresponds to the sum and product signs. solve() solves equations (ex. solve(x * 2 = 8) returns 4 meaning that x equals 4). Use solve2() and multisolve() to solve multiple equations with multiple variables. + + + +Calculus + +Includes diff(), which calculates the derivative of an expression with optional arguments with respect to (default x) and order (default 1), and a limited integration function. + + + +Combinatorics + +Contains functions such as perm() for permutations, comb() for combinations, and factorial(). + + + +Data Sets + +A data set consists of a set of properties and objects, which can be accessed by a function which takes two arguments — object and property. The function returns the object's value for the selected property. +For example, the data in the Elements data set is accessed with the atom() function, with the element (referenced using atomic symbol, number or name) and property (ex. weight) as arguments. +The special property info displays all properties of the object in a dialog window. + + + +Date & Time + +Includes days() and yearfrac() which returns the number of days and fractional years, respectively, between two dates. + + + +Exponents & Logarithms + +Standard logarithmic and exponential functions. ln() calculates the natural logarithm of a number, while log() allows a choice of base as the second argument. The exponential functions does not really add anything beyond the capabilities of the exponential operator, ^. + + + +Economics + +This essentially includes most of the financial functions that are usually found in spreadsheet applications. + + + +Elements + +This category includes functions to retrieve data such as atomic weight. The atom() function opens a window with available data of an element. These functions accept the number, symbol or name of the element as argument. The data are loaded on demand. + + + +Geometry + +Category with formulas mostly for calculation of circumference, area and volume of geometric shapes. + + + +Logical + +Some procedural functions mainly for use in other functions. These include if(), which tests a conditional expression and returns a value depending on if the expression evaluates true or false, and for(), which processes a value while a condition is true. + + + +Matrices & Vectors + +These are functions that generate, access and process matrices and vectors. The vector() function generates a vector from a variable number of arguments for elements, while matrix() first needs the number of rows and columns and then the elements from left to right. Matrices can also be imported directly from a CSV file with load(). + + +Separate elements at a specified row and column are accessed with element(). Other functions include det() for calculation of the determinant of a matrix and inverse() which returns the inverse of the given matrix, as well as functions such as sort() and rank(). + + + +Miscellaneous + +A category for functions that do not fit elsewhere. + + + +Number Theory + +Contains subcategories arithmetics, number bases, and rounding, in addition to functions such as abs(), which returns the absolute value of a number, and gcd(), the greatest common divisor. round() is the standard rounding function (note that halfway numbers are rounded to even). The functions for number bases translates a text string, representing an expression (bases that use letters does not allow variables, functions and units) with numbers in a different base, to a decimal number. Includes bin() for binary numbers, hex() for hexadecimal numbers, oct() for octal numbers and base() for numbers in a base between 2 and 36 specified in the second argument. + + + +Statistics + +Contains a lot of functions for descriptive statistics and some statistical tests. Data sets are stored as vectors. Generally, functions with a vector/data set as last argument can take elements/samples as a variable number of arguments directly instead of in a vector (ex. mean(1, 2, 3) equals mean(vector(1, 2, 3))). Also contains the rand() function, which returns a pseudo random number between 0 and 1, and does not take any arguments. + + + +Trigonometry + +Trigonometric functions, including sin(), cos(), tan(), sec(), csc(), cot(), and hyperbolic and inverse versions of those. These functions take as argument an angle. If the default angle unit (ModeAngle Unit) is set to none, the argument must have an angle unit appended (degrees, radians or gradians), otherwise the default unit will be appended automatically (and removed from result of inverse functions). + + + +Utilities + +Various utility functions. Most are only useful in definition of other functions. The save() function can however be a quick way of storing a value in a variable, and csum() can be a powerful tool for data processing. This category also contains some functions, such as char() and ascii(), that might be useful for programmers. , replace() provides an easy way of replacing unknown variables by known expressions in a value (ex. replace(5x^2+x, x, 3) equals 5*3^2+3). + + + + + + +Function creation/editing + +Functions are a bit more complex than variables, but can nevertheless be relatively easily created. FileNewFunction or click New in the function manager and the function edit dialog pops up. This dialog consists of two tabs/pages; the first with general descriptive information and the last for the function definition. First enter a name, used to reference the function in an expression. If an expression is entered a bit further down, then the function will already be fully working. A bit more does however need to be said about the function expression. + + +The expression of a function is basically a normal expression with placeholders for arguments. These placeholders consists of a backslash and a letter — x, y, z for the 1st, 2nd and 3rd arguments and a to u for argument 4 to 24. They are replaced by entered arguments when a function is calculated. The placeholders naturally also decide the number of arguments that a function requires. For example the function for triangle area (base * height / 2) has the name triangle and the expression (\x*\y)/2, which gives that triangle(2, 3) equals (2*3) / 2 and returns 3 as result. An argument can be used more than one time and all arguments must not necessarily be in order in the expression. +
+ Function Edit Dialog + + + + + + + +
+
+ +Additionally, optional arguments can be put in the expression with upper-case (X, Y, Z, ...) instead of lower-case letters (x, y, z, ...). The default value can be put in brackets after the letter (ex. \X{2}). The default value may be omitted and is then zero. All additional arguments after an optional argument must also be optional. + + +A condition that must be true (>0) for the function to be calculated, can optionally be entered in the text field below the expression. This follows the same conventions as function expressions. For example if the second argument must be higher than the first, \y > \x may be entered as condition. + + +Further, name, type and condition for each argument can be specified. + + +To keep functions well organized, supply a category, descriptive name and description. A function can also hidden from menus with the corresponding check box, which can be useful for sub functions. + + +Global, system-wide functions can not actually be changed by the user, but if one of these functions is edited, they are deactivated and seemingly replaced by a new function. This way global functions can be deleted by deactivation. Some functions are however hard-coded and cannot be changed by the user. + +
+
+ + +Units + +Units give numbers meaning in the real world. They specify what is measured by the numbers and the scale used. Qalculate! fully incorporates units in calculations and includes all standard SI units as well as many non-standard local units. +For a complete list of available units see or the unit manager. + + +Currency + +Among units, Qalculate! has support for currencies with up-to-date exchange rates. Currencies are normally referenced with the standard three letter code due to name clashes, but a number of currency unit can also be accessed through their regular name and symbol. U.S. dollars can, for example, be referenced both as USD and dollar/dollars, or with the $ symbol. + + +Current exchange rates are automatically fetched from the European Central Bank on the Internet, the first time Qalculate! is started. By default the exchange rates will thereafter have to be updated manually from FileUpdate Exchange Rates, unless automatic updates are enabled in the preferences dialog. + + + +Conversion + +Expressions can be converted to a specific unit directly in the expression entry with the to operator, which converts the left-hand expression to a specified unit (ex. 5 feet + 2 inches to cm converts the result of 5 feet + 2 inches to centimeters and displays it). Unit expressions may only contain units, prefixes, exponents, multiplication and division. Other elements are ignored. + + +The unit conversion dialog, accessible from the Convert button, EditConvert To Unit Expression... or CtrlT, can also be used. Enter a unit in the dialog that pops up, click Apply or OK and the displayed result is then converted. In this dialog, you can also select a unit from a list accessed by clicking Selector >>. When a unit is selected from the list the expression is updated and Apply automatically pressed. +
+ Unit Conversion Dialog + + + + + + + +
+
+ +The final way to convert to another unit is to use the predefined units in the EditConvert To Unit menu or press Convert Result in the unit manager. EditSet Prefix can be used to select a prefix. + + +It is also possible to let Qalculate! automagically convert the result to appropriate units with EditConvert To Best Unit or EditConvert To Base Units. If instead the corresponding choice is selected from ModeUnit Display, each result will automatically be converted until the choice is deactivated (ModeUnit DisplayNo Automatic Conversion). + +
+ +Unit creation/editing + +There are three different unit classes in Qalculate! — base, alias and composite units. Base units are units defined as basis for other units. Meters and seconds are typical base units. Alias units is defined in relation to another unit. For example, hour is defined as an alias unit that equals 60 minutes which in turn is defined in relation to seconds. Finally, composite units are defined by a unit expression with multiple units. Composite units often have an alias unit associated with them, as they do not have a reference name on their own. For example, a joule is defined as an alias defined in relation to a composite unit defined as Newton * meter. + + +Select FileNewUnit, or click New in the unit manager, and the unit edit dialog pops up. +
+ Unit Edit Dialog + + + + + + + +
+First the unit class needs to be selected. Depending on the unit class, different elements in the dialog will be enabled. For all units, category and descriptive name can be specified to keep them well organized. A unit can also be hidden from unit menus with the corresponding check box, which can be useful for some composite units. +
+ +Base and alias units normally have three different name forms defined for use in expressions — abbreviation (ex. m), singular (meter) and plural (meters). Composite units only have an internal name, used to reference the unit in definitions of other units. + + +For base units, the name is all that is needed. For alias units, on the other hand, a base unit, exponent and relation are necessary. For more complex relations an inverse relation can also be specified for conversion back from the base unit. The base unit must not necessarily be of the base unit class and it is recommended that an alias unit is defined in relation to the closest unit (ex. 1ft = 3 hands, 1 hand = 4 in, and 1 in = 0.0254 m). The relation is usually just a number that tells how large quantity of the base unit is needed to get the alias unit (alias unit = base unit * relation). More complex units can specify the relation as a full-blown expression where \x is replaced by the quantity of the base unit and \y is the exponent. For example, Degrees Celsius has the relation \x + 273.15 and the inverse relation \x − 273.15 to the base unit Kelvin. For simple relations, the reversion is automatic and ought not be defined separately. The check box below relation in the dialog specifies if the relation is exact or approximate. The exponent defines the exponential relation to the base unit, so that the alias unit equals the base unit raised to the exponent. For simple unit relations this gives: alias unit = relation * base unit^exponent. + + +Composite units need a unit expression with multiple units as base, in the base unit field. These expressions may only contain units, prefixes, exponents, multiplication and division (ex. km/h). + +
+
+ + +Plotting + +Plotting in Qalculate! is done through an external program, Gnuplot. Thus Gnuplot (>= v. 3.7) need to be installed on the computer for plotting to work. + + +To plot functions or data sets, select FilePlot Functions/Data, which brings up the plot dialog. The plot dialog consists of three tabs/pages — the first for the data, the second for the function range and sampling rate, and the last for control of function sampling and appearance. + +
+ Plot Data + + + + + + + +
+ +Plot functions are normal expressions that represents f(x) in y=f(x) (ex. sin(x)). The x can be specified as a different unknown variable (x, y, z) or a quoted text string (actually any mathematical expression which will then be matched in the plot expression and replaced by the values on the x axis) in the variable entry below the function/data list. + + +To plot a data set, enter an expression that results in a matrix or vector. Select Vector/Matrix below and vectors will appear as one series and matrices will appear with each column or row (if selected) as a series, If the paired matrix option instead is selected, the first column/row of the matrix will constitute the y-values and the second the x-values. + + +Type in an expression, press Enter and a new window will open with the plot. The title of the series, the diagram style and smoothing of the line can also be set. The series modified must be selected in the list and to apply changes click Apply. More series that will appear in the same plot window can be added. If the scale of the y values differ, series can be put on a secondary y-axis. + + + +Even though Qalculate! does all the calculations before handing over the data to Gnuplot, the resulting data must only consist of pure numbers, as Gnuplot knows nothing about the functions, variables, units, etc. of Qalculate!. + + + +For functions, the function range — min and max x value, and the number of values or the size of the step between each y value calculated — can be specified in the function range page. + +
+ Plot Settings + + + + + + + +
+ +A title can be set to appear at the top of the plot, as well as labels for the x and y axis. The appearance can also be controlled by selecting or disabling legend placement, displaying/hiding the grid and borders on the top and the right side of the diagram and choosing color or monochrome graphics. The x and y scales can be made logarithmic by clicking the box on the right and filling in a desired logarithmic base. + + +To update the plot window, click Apply at the bottom of the dialog. + +
+ Gnuplot + + + + + + + +
+ +The plot can be saved as an image file. Click Save and select a file name and folder. The extension of the file name will decide the file type (.png for PNG image, .svg for SVG, .ps for postscript, .eps for encapsulated postscript, .tex for LaTeX, and .fig for XFig). Default is to save as a PNG image. + +
+ + + + + +Credits and License + + +&qalculate_kde; + + +Program copyright 2005 Niklas Knutsson nq@altern.org + + + +Documentation copyright 2005 Niklas Knutsson nq@altern.org + + + + +&underFDL; + + + +&underGPL; + + + +&functionlist; +&variablelist; +&unitlist; + +&documentation.index; + + + + diff --git a/doc/en/qalculate_kde/insert-function.png b/doc/en/qalculate_kde/insert-function.png new file mode 100644 index 0000000000000000000000000000000000000000..559e876672438297188b8bc329d77218fb5f55f4 GIT binary patch literal 60742 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

I$l%a{q*?VAlQ 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 literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/units.docbook b/doc/en/qalculate_kde/units.docbook new file mode 100644 index 0000000..0020f2d --- /dev/null +++ b/doc/en/qalculate_kde/units.docbook @@ -0,0 +1,3455 @@ + +Unit List + +Angle + +Angular Acceleration + +Units: Angular Acceleration + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Radians per Second Squared +(rad_p_sqs) +rad/s^2 + + + + +
+
+ +Angular Velocity + +Units: Angular Velocity + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Radians per Second +(rad_p_s) +rad/s + + + + +
+
+ +Plane Angle + +Units: Plane Angle + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Arcminute +arcminute / arcminutes +° +1/60 + + +Arcsecond +arcsecond / arcseconds +arcminute +1/60 + + +Degree +deg / ° / degree / degrees +rad +pi/180 + + +Gradian (Gon) +gra / gradian / gradians / gon / gons +rad +pi/200 + + +Meter per Meter +(m_p_m) +m/m + + + +Radian +rad / radian / radians +m_p_m +1 + + +Turn +turn / turns +° +360 + + + +
+
+ +Solid Angle + +Units: Solid Angle + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Square Meter per Square Meter +(sqm_p_sqm) +m^2/m^2 + + + +Steradian +sr / steradian / steradians +m_p_m +1 + + + +
+
+
+ +Area + +Units: Area + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Acre +acre / acres +ch^2 +10 + + +Are +a / are / ares +m^2 +100 + + +Barn +b / barn / barns +m^2 +1E-28 + + +Hectare +(ha) +ha + + + +Rood +rood / roods +yd^2 +1210 + + +Section +section / sections +mi^2 +1 + + +Square Foot +(sqft) +ft^2 + + + +Square Inch +(sqin) +in^2 + + + +Square Kilometer +(sqkm) +km^2 + + + +Square Meter +(sqm) +m^2 + + + +Square Mile +(sqmi) +mi^2 + + + +Township +township / townships +section +36 + + + +
+
+ +Currency + +Units: Currency + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Australian Dollars +AUD + +exchange rate + + +Austrian Schilling +ATS / schilling + +1/13.7603 + + +Belgian Franc +BEF + +1/40.3399 + + +British Pounds +GBP / £ + +exchange rate + + +Bulgarian Lev +lev / BGN + +exchange rate + + +Canadian Dollars +CAD + +exchange rate + + +Cent (USD) +¢ / cent / cents +$ +1/100 + + +Croatian Kuna +HRK + +exchange rate + + +Cypriot Pound +CYP + +exchange rate + + +Czech Koruna +CZK + +exchange rate + + +Danish Kroner +DKK + +exchange rate + + +Deutche Mark +DEM / mark + +1/1.95583 + + +Dutch Guilder +NLG / guilder + +1/2.20371 + + +Estonian Kroon +EEK + +exchange rate + + +Euro Cent +eurocent / eurocents + +1/100 + + +European Euros +EUR / € / euro / euros + + + + +Finnish Markka +FIM / markka + +1/5.94573 + + +French Franc +FRF / franc + +1/6.55957 + + +Greek Drachma +GRD + +1/340.750 + + +Hong Kong Dollars +HKD + +exchange rate + + +Hungarian Forint +forint / HUF + +exchange rate + + +Icelandic Krona +ISK + +exchange rate + + +Indonesian Rupiah +IDR + +exchange rate + + +Irish Pound +IEP + +1/0.787564 + + +Italian Lira +ITL / lira + +1/1936.27 + + +Japanese Yen +JPY / ¥ / yen + +exchange rate + + +Latvian Lat +lat / LVL + +exchange rate + + +Lithuanian Lit +lit / LTL + +exchange rate + + +Luxembourg Franc +LUF + +1/40.3399 + + +Malaysian Ringgit +MYR + +exchange rate + + +Maltese Lira +MTL + +exchange rate + + +New Zealand Dollars +NZD + +exchange rate + + +Norwegian Kroner +NOK + +exchange rate + + +Phillipine Peso +PHP + +exchange rate + + +Polish Zloty +zloty / PLN + +exchange rate + + +Portuguese Escudo +PTE / escudo + +1/200.482 + + +Romanian New Leu +leu / RON + +exchange rate + + +Russian Ruble +RUB / ruble + +exchange rate + + +Singapore Dollars +SGD + +exchange rate + + +Slovakian Koruna +SKK + +exchange rate + + +Slovenian Tolar +tolar / SIT + +exchange rate + + +South African Rand +ZAR + +exchange rate + + +South Korean Won +KRW + +exchange rate + + +Spanish Peseta +ESP / peseta / pesetas + +1/166.386 + + +Swedish Krona +SEK + +exchange rate + + +Swiss Francs +CHF + +exchange rate + + +Thai Bat +THB + +exchange rate + + +Turkish New Lira +TRY + +exchange rate + + +U.S. Dollars +$ / USD / dollar / dollars + +exchange rate + + +Yuan Renmimbi (PR China) +CNY + +exchange rate + + + +
+
+ +Electricity + +Capacitance + +Units: Capacitance + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Coulomb per Volt +(C_p_V) +C/V + + + +Farad +F / farad / farads +C_p_V +1 + + + +
+
+ +Current Density + +Units: Current Density + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Ampere per Meter Squared +(A_p_sqm) +A/m^2 + + + + +
+
+ +Electric Charge + +Units: Electric Charge + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Abcoulomb +abcoulomb / abcoulombs / abC / aC +C +10 + + +Coulomb +C / coulomb / coulombs +s_A +1 + + +Second Ampere +(s_A) +s A + + + +Statcoloumb (Franklin) +statcoulomb / statcoulombs / statC / franklin / Fr / franklins +C +3.3356410E-10 (approximate) + + + +
+
+ +Electric Charge Density + +Units: Electric Charge Density + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Coulomb per Cubic Meter +(C_p_cum) +C/m^3 + + + + +
+
+ +Electric Conductance + +Units: Electric Conductance + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Ampere per Volt +(A_p_V) +A/V + + + +Siemens +S / siemens +A_p_V +1 + + + +
+
+ +Electric Current + +Units: Electric Current + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Abampere +abampere / abA / aA / abamperes +A +10 + + +Ampere +A / ampere / amperes + + + + + +
+
+ +Electric Field Strength + +Units: Electric Field Strength + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Volt per Meter +(V_p_m) +V/m + + + + +
+
+ +Electric Flux Density + +Units: Electric Flux Density + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Coulomb per Meter Squared +(C_p_sqm) +C/m^2 + + + + +
+
+ +Electric Potential + +Units: Electric Potential + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Abvolt +abvolt / abvolts / abV +V +1E-8 + + +Statvolt +statvolt / statvolts / statV +V +299.792458 + + +Volt +V / volt / volts +W_p_A +1 + + +Watt per Ampere +(W_p_A) +W/A + + + + +
+
+ +Electric Resistance + +Units: Electric Resistance + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Abohm +abohm / abohms / abΩ +Ω +1E-9 + + +Ohm +Ω / ohm / ohms +V_p_A +1 + + +Statohm +statohm / statohms / statΩ +Ω +8.9875517874E11 (approximate) + + +Volt per Ampere +(V_p_A) +V/A + + + + +
+
+ +Inductance + +Units: Inductance + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Henry +H / henry / henrys +Wb_p_A +1 + + +Weber per Ampere +(Wb_p_A) +Wb/A + + + + +
+
+ +Permeability + +Units: Permeability + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Henry per Meter +(H_p_m) +H/m + + + + +
+
+ +Permittivity + +Units: Permittivity + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Farad per Meter +(F_p_m) +F/m + + + + +
+
+
+ +Energy + +Units: Energy + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +British Thermal Unit (IT) +Btu +J +1055.056 + + +Calorie (15 degrees Celcius) +cal_fifteen +J +4.185880 (approximate) + + +Calorie (capital C) +Calorie / Calories +cal_IT +1000 + + +Calorie (international table) +cal_IT / cal / calorie / calories +J +4.1868 + + +Calorie (mean) +cal_mean +J +4.19002 (approximate) + + +Calorie (thermochemical) +cal_th +J +4.184 + + +Electron Volt +eV / electron_volt / electron_volts +J +1.602177E-19 (approximate) + + +Erg +erg / ergs +J +1E-7 + + +Foe +foe / foes +erg +1E51 + + +Foot-Pound Force +(ft_lbf) +ft lbf + + + +Joule +J / joule / joules +N_m +1 + + +Kilowatt Hour +(W_h) +kW h + + + +Watt Hour +(W_h) +W h + + + + +
+ +Energy Density + +Units: Energy Density + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Joule per Cubic Meter +(J_p_cum) +J/m^3 + + + + +
+
+ +Entropy + +Units: Entropy + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Joule per Kelvin +(J_p_K) +J/K + + + + +
+
+ +Molar Energy + +Units: Molar Energy + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Joule per Mole +(J_p_mol) +J/mol + + + + +
+
+ +Molar Entropy + +Units: Molar Entropy + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Joule per Mole Kelvin +(J_p_mol_K) +J/(mol K) + + + + +
+
+ +Power + +Units: Power + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Horse Power +hp / horsepower / horsepowers +W +745.699987158227022 + + +Joule per Second +(J_p_s) +J/s + + + +Pferdestärke +PS / pferdestärke +W +735.49875 + + +Watt +W / watt / watts +J_p_s +1 + + + +
+
+ +Specific Energy + +Units: Specific Energy + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Joule per Kilogram +(J_p_kg) +J/kg + + + + +
+
+ +Specific Entropy + +Units: Specific Entropy + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Joule per Kilogram Kelvin +(J_p_kg_K) +J/(kg K) + + + + +
+
+ +Thermal Conductivity + +Units: Thermal Conductivity + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Watt per Meter Kelvin +(W_p_m_K) +W/(m K) + + + + +
+
+
+ +Force + +Units: Force + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Dyne +dyn / dyne / dynes +N +1E-5 + + +Kilopond (Kilogram-Force) +(kpond_c) +kpond + + + +Meter Kilogram per Second Squared +(m_kg_p_sqs) +m kg/s^2 + + + +Newton +N / newton / newtons +m_kg_p_sqs +1 + + +Pond (Gram-Force) +pond / ponds / gf +N +0.00980665 + + +Pound Foot per Second Squared +(lb_ft_p_sqs) +lb ft/s^2 + + + +Pound-force +lbf / pound_force +N +4.4482216152605 + + +Poundal +poundal / poundals / pdl +lb_ft_p_sqs +1 + + + +
+ +Dynamic Viscosity + +Units: Dynamic Viscosity + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Pascal Second +(Pa_s) +Pa s + + + +Poise +P / poise / poises +Pa_s +0.1 + + + +
+
+ +Kinematic Viscosity + +Units: Kinematic Viscosity + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Square Meter per Second +(sqm_p_s) +m^2/s + + + +Stokes +St / stokes +sqm_p_s +0.0001 + + + +
+
+ +Moment of Force + +Units: Moment of Force + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Newton Meter +(N_m) +N m + + + + +
+
+ +Pressure + +Units: Pressure + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Atmosphere +atm / atmosphere / atmospheres +Pa +101325 + + +Bar +bar / bars +Pa +100000 + + +Millimeter of Mercury +mmHg +atm +1/760 + + +Newton per Meter Squared +(N_p_sqm) +N/m^2 + + + +Pascal +Pa / pascal / pascals +N_p_sqm +1 + + +Pound-force per Square Inch +(lbf_p_sqin) +lbf/in^2 + + + +Pound-force per Square Inch (psi) +psi +lbf_p_sqin +1 + + +Torr +torr / torrs +atm +1/760 + + + +
+
+ +Surface Tension + +Units: Surface Tension + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Newton per Meter +(N_p_m) +N/m + + + + +
+
+
+ +Information + +Units: Information + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Bit +bit / bits + + + + +Byte (8-bit) +byte / bytes / octet / octets +bit +8 + + +Gibibit +(Gibit_c) +Gibit + + + +Gibibyte +(Gibyte_c) +Gibyte + + + +Gigabit +(Gbit_c) +Gbit + + + +Gigabyte +(Gbyte_c) +Gbyte + + + +Kibibit +(Kibit_c) +Kibit + + + +Kibibyte +(Kibyte_c) +Kibyte + + + +Kilobit +(kbit_c) +kbit + + + +Kilobyte +(kbyte_c) +kbyte + + + +Mebibit +(Mibit_c) +Mibit + + + +Mebibyte +(Mibyte_c) +Mibyte + + + +Megabit +(Mbit_c) +Mbit + + + +Megabyte +(Mbyte_c) +Mbyte + + + +Nibble +nibble / nibbles / nybble / nybbles / semioctet / semioctets +bit +4 + + +Terabit +(Tbit_c) +Tbit + + + +Terabyte +(Tbyte_c) +Tbyte + + + +Tribble +tribble / tribbles +nibble +3 + + +Word (16-bit) +word / words +bit +16 + + + +
+
+ +Length + +Units: Length + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Astronomical Unit +AU / astronomical_unit / astronomical_units +m +149578706600 + + +Centimeter +(cm_c) +cm + + + +Chain +ch / chain / chains +li +100 + + +Decimeter +(dm_c) +dm + + + +Fathom +fathom / fathoms +yd +2 + + +Foot +ft / foot / feet +hand +3 + + +Furlong +fur / furlong / furlongs +yd +220 + + +Hand +hand / hands +in +4 + + +Inch +in / inch / inches +m +0.0254 + + +Kilometer +(km_c) +km + + + +Light Year +ly / lightyear / lightyears +m +9460730472580800 + + +Link +li / link / links +ft +66/100 + + +Meter +m / meter / meters / metre / metres + + + + +Mil (1/1000 in) +mil / mils +in +0.001 + + +Mile +mi / mile / miles +ch +80 + + +Millimeter +(mm_c) +mm + + + +Nautical Mile +nautical_mile / nautical_miles +m +1852 + + +Parsec +pc / parsec / parsecs +AU +648000/pi + + +Rod (pole/perch) +rd / rod / rods +US_ft +16.5 + + +U.S. Survey Foot +US_ft / US_foot / US_feet +US_in +12 + + +U.S. Survey Inch +US_in / US_inch / US_inches +m +100/3937 + + +U.S. Survey Mile +US_mi / US_mile / US_miles +US_ft +5280 + + +Yard +yd / yard / yards +ft +3 + + +Ångström +Å / ångström / angstrom +m +1E-10 + + + +
+
+ +Light + +Illuminance + +Units: Illuminance + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Foot-Candle +fc / footcandle / footcandles +lm_p_sqft +1 + + +Lumen per Foot Squared +(lm_p_sqft) +lm/ft^2 + + + +Lumen per Meter Squared +(lm_p_sqm) +lm/m^2 + + + +Lux +lx / lux +lm_p_sqm +1 + + +Phot +ph / phot / phots +lx +10000 + + + +
+
+ +Irradiance + +Units: Irradiance + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Einstein per Meter Squared per Second +(einstein_p_sqm_p_s) +einstein/(s m^2) + + + +Microeinstein per Meter Squared per Second +(microeinstein_p_sqm_p_s) +µeinstein/(s m^2) + + + +Watt per Meter Squared +(W_p_sqm) +W/m^2 + + + + +
+
+ +Luminance + +Units: Luminance + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Candela per Meter Squared +(cd_p_sqm) +cd/m^2 + + + +Stilb +sb / stilb / stilbs +cd_p_sqm +10000 + + + +
+
+ +Luminous Flux + +Units: Luminous Flux + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Candela Steradian +(cd_sr) +cd sr + + + +Lumen +lm / lumen / lumens +cd_sr +1 + + + +
+
+ +Luminous Intensity + +Units: Luminous Intensity + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Candela +cd / candela / candelas + + + + + +
+
+ +Radiance + +Units: Radiance + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Watt per Square Meter Steradian +(W_p_sqm_sr) +W/(sr m^2) + + + + +
+
+ +Radiant Intensity + +Units: Radiant Intensity + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Watt per Steradian +(W_p_sr) +W/sr + + + + +
+
+
+ +Magnetism + +Magnetic Field Strength + +Units: Magnetic Field Strength + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Ampere per Meter +(A_p_m) +A/m + + + +Oersted +Oe / oersted / oersteds +A_p_m +1000/(4*pi) + + + +
+
+ +Magnetic Flux + +Units: Magnetic Flux + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Maxwell +Mx / maxwell / maxwells +Wb +1E-8 + + +Volt Seconds +(V_s) +V s + + + +Weber +Wb / weber / webers +V_s +1 + + + +
+
+ +Magnetic Flux Density + +Units: Magnetic Flux Density + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Gauss +gauss +T +0.0001 + + +Tesla +T / tesla / teslas +Wb_p_sqm +1 + + +Weber per Meter Squared +(Wb_p_sqm) +Wb/m^2 + + + + +
+
+ +Wave Number + +Units: Wave Number + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Reciprocal Meter +(recm) +m^-1 + + + + +
+
+
+ +Mass + +Units: Mass + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Carat +carat / carats +g +0.2 + + +Cental +cental / centals +lb +100 + + +Dram +dr / dram / drams +g +1.7718451953125 + + +Grain +gr / grain / grains +g +0.06479891 + + +Gram +g / gram / grams + + + + +Hektogram +(hg_c) +hg + + + +Kilogram +(kg_c) +kg + + + +Long Hundredweight +l_cwt / long_hundredweight / long_hundredweights +lb +112 + + +Long Ton +l_ton / long_ton / long_tons +lb +2240 + + +Metric Ton (Tonne) +t / tonne / tonnes / ton / tons +g +1000000 + + +Ounce +oz / ounce / ounces +dr +16 + + +Ounce (troy) +oz_t / troy_ounce / troy_ounces +pwt +20 + + +Pennyweight +pwt / pennyweight / pennyweights +gr +24 + + +Pfund +pfund +g +500 + + +Pound +lb / pound / pounds +oz +16 + + +Pound (troy) +lb_t / troy_pound / troy_pounds +oz_t +12 + + +Short Hundredweight +cwt / hundredweight / hundredweights +lb +100 + + +Short Ton +s_ton / short_ton / short_tons +lb +2000 + + +Stone +stone / stones +lb +14 + + +Zentner +zentner +pfund +100 + + + +
+ +Density + +Units: Density + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Atomic Mass Unit +u / atomic_mass_unit / atomic_mass_units +g_p_mol +1 + + +Gram per Cubic Centimeter +(g_p_cucm) +g/cm^3 + + + +Gram per Cubic Decimeter +(g_p_cudm) +g/dm^3 + + + +Gram per Mole +(g_p_mol) +g/mol + + + +Kilogram per Cubic Meter +(kg_p_cum) +kg/m^3 + + + + +
+
+ +Mass Fraction + +Units: Mass Fraction + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Kilogram per Kilogram +(kg_p_kg) +kg/kg + + + + +
+
+
+ +Radioactivity + +Units: Radioactivity + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Becquerel +Bq / becquerel / becquerels +s^-1 +1 + + +Curie +Ci / curie / curies +Bq +3.7E10 + + + +
+ +Absorbed Dose + +Units: Absorbed Dose + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Gray +Gy / gray / grays +J_p_kg +1 + + +Rad +rad_radioactivity +Gy +1/100 + + + +
+
+ +Absorbed Dose Rate + +Units: Absorbed Dose Rate + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Gray per Second +(Gy_p_s) +Gy/s + + + + +
+
+ +Dose Equivalent + +Units: Dose Equivalent + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Rem +rem_radioactivity +Sv +1/100 + + +Sievert +Sv / sievert / sieverts +J_p_kg +1 + + + +
+
+ +Exposure + +Units: Exposure + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Coulomb per Kilogram +(C_p_kg) +C/kg + + + +Roentgen +R / roentgen / roentgens +C_p_kg +0.000258 + + + +
+
+
+ +Ratio + +Units: Ratio + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Bel +B / bel / bels +Np +0.5*ln(10) + + +Decibel +(dB_c) +dB + + + +Neper +Np / neper / nepers + + + + + +
+
+ +Speed + +Units: Speed + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Kilometer per Hour +(km_p_h) +km/h + + + +Knot +knot / knots +nautical_mile_p_h +1 + + +Meter per Second +(m_p_s) +m/s + + + +Miles per Hour +(mile_p_h) +mi/h + + + +Miles per Hour +mph +mile_p_h +1 + + +Nautical Mile per Hour +(nautical_mile_p_h) +nautical_mile/h + + + + +
+ +Acceleration + +Units: Acceleration + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Galileo +Gal / galileo / galileos +m_p_sqs +1/100 + + +Gee +gee / gees +m_p_sqs +9.80665 + + +Meter per Second Squared +(m_p_sqs) +m/s^2 + + + + +
+
+
+ +Substance + +Units: Substance + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Einstein +einstein / einsteins + + + + +Mole +mol / mole / moles + + + + + +
+ +Catalytic Activity + +Units: Catalytic Activity + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Katal +kat / katal / katals +recs_mol +1 + + +Reciprocal Seconds Mole +(recs_mol) +mol/s + + + + +
+
+ +Catalytic Concentration + +Units: Catalytic Concentration + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Katal per Cubic Meter +(kat_p_cum) +kat/m^3 + + + + +
+
+ +Substance Concentration + +Units: Substance Concentration + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Mole per Cubic Meter +(mol_p_cum) +mol/m^3 + + + + +
+
+
+ +Temperature + +Units: Temperature + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Degree Celcius +oC / °C / celcius +K +\x + 273.15 + + +Degrees Fahrenheit +oF / °F / fahrenheit +K +(2298.35+5\x)/9 + + +Degrees Rankine +oR / °R / rankine +K +5\x/9 + + +Kelvin +K / kelvin / kelvins + + + + + +
+
+ +Time + +Units: Time + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Day +d / day / days +h +24 + + +Fortnight +fortnight / fortnights +week +2 + + +Hour +h / hour / hours +min +60 + + +Julian Year +year / years +d +365.25 + + +Minute +min / minute / minutes +s +60 + + +Second +s / second / seconds + + + + +Week +week / weeks +d +7 + + + +
+ +Frequency + +Units: Frequency + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Hertz +Hz / hertz +s^-1 +1 + + + +
+
+
+ +Volume + +Units: Volume + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Centiliter +(cl_c) +cL + + + +Cubic Inch +(cuin) +in^3 + + + +Cubic Meter +(cum) +m^3 + + + +Deciliter +(dl_c) +dL + + + +Liter +L / l / liter / liters / litre / litres +m^3 +0.001 + + +Milliliter +(ml_c) +mL + + + + +
+ +Cooking + +Units: Cooking + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Cup +cup / cups +L +0.250 + + +Dessertspoon +dessertspoon / dessertspoons +teaspoon +2 + + +Tablespoon +tablespoon / tablespoons +teaspoon +3 + + +Teaspoon +teaspoon / teaspoons +L +0.005 + + + +
+
+ +Fuel Economy + +Units: Fuel Economy + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Kilometer per Liter +(km_p_l) +km/L + + + +Liter per Kilometer +(l_p_km) +L/km + + + +Miles per Gallon +(mile_p_gal) +mi/gal + + + +Miles per Gallon +mpg +mile_p_gal +1 + + + +
+
+ +Imperial Capacity + +Units: Imperial Capacity + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Imperial Bushel +UK_bu / imperial_bushel / imperial_bushels +UK_gal +8 + + +Imperial Fluid Drachm +UK_fl_dr / imperial_fluid_drachm / imperial_fluid_drachms +imperial_fluid_scuple +3 + + +Imperial Fluid Ounce +UK_fl_oz / imperial_fluid_ounce / imperial_fluid_ounces +L +0.0284130625 + + +Imperial Fluid Scuple +imperial_fluid_scuple / imperial_fluid_scuples +imperial_minim +20 + + +Imperial Gallon +UK_gal / imperial_gallon / imperial_gallons +UK_qt +4 + + +Imperial Gill +UK_gi / imperial_gill / imperial_gills +UK_fl_oz +5 + + +Imperial Minim +imperial_minim / imperial_minims +UK_fl_oz +1/480 + + +Imperial Pint +UK_pt / imperial_pint / imperial_pints +UK_gi +4 + + +Imperial Quart +UK_qt / imperial_quart / imperial_quarts +UK_pt +2 + + + +
+
+ +Specific Volume + +Units: Specific Volume + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +Cubic Meter per Kilogram +(cum_p_kg) +m^3/kg + + + + +
+
+ +U.S. Capacity + +Units: U.S. Capacity + + + + + + + +Title +Names +Base Unit(s) +Relation + + + + +U.S. Barrell (oil) +bbl / barrell / barrells +gal +42 + + +U.S. Bushel +bu / bushel / bushels +pk +4 + + +U.S. Dry Pint +dry_pt / dry_pint / dry_pints +in^3 +33.6003125 + + +U.S. Dry Quart +dry_qt / dry_quart / dry_quarts +dry_pt +2 + + +U.S. Fluid Drachm +fl_dr / fluid_drachm / fluid_drachms +minim +60 + + +U.S. Fluid Ounce +fl_oz / fluid_ounce / fluid_ounces +in^3 +231/128 + + +U.S. Gallon +gal / gallon / gallons +liq_qt +4 + + +U.S. Gill +gi / gill / gills +fl_oz +4 + + +U.S. Liquid Pints +liq_pt / liquid_pint / liquid_pints +gi +4 + + +U.S. Liquid Quarts +liq_qt / liquid_quart / liquid_quarts +liq_pt +2 + + +U.S. Minim +minim / minims +fl_oz +1/480 + + +U.S. Peck +pk / peck / pecks +dry_qt +8 + + + +
+
+
+
diff --git a/doc/en/qalculate_kde/variable-manager.png b/doc/en/qalculate_kde/variable-manager.png new file mode 100644 index 0000000000000000000000000000000000000000..b33d9ea080da309037da518dba44080b570094f3 GIT binary patch literal 52390 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 j5g@;gi0w%bJ%2=itH)!=GZnXuf`9iU +Variable List + +Basic Constants + +Variables: Basic Constants + + + + + + +Title +Names +Value + + + + +Apery's Constant +apery +zeta(3) + + +Archimede's Constant (pi) +π / pi +3.1415927 (approximate) + + +Catalan's Constant +catalan +0.91596559 (approximate) + + +Euler's Constant +γ / euler +0.57721566 (approximate) + + +Pythagora's Constant (sqrt 2) +pythagoras +sqrt(2) + + +The Base of Natural Logarithms (e) +e +2.7182818 (approximate) + + +The Golden Ratio +golden / φ +(1+sqrt(5))/2 + + + +
+
+ +Large Numbers + +Variables: Large Numbers + + + + + + +Title +Names +Value + + + + +Billion +billion +1E9 + + +Centillion +centillion +1E303 + + +Decillion +decillion +1E33 + + +Duodecillion +duodecillion +1E39 + + +Googol +googol +10^100 + + +Googolplex +googolplex +10^(10^100) + + +Hundred +hundred +1E2 + + +Million +million +1E6 + + +Nonillion +nonillion +1E30 + + +Novemdecillion +novemdecillion +1E60 + + +Octillion +octillion +1E27 + + +Octodecillion +octodecillion +1E57 + + +Quadrillion +quadrillion +1E15 + + +Quattuordecillion +quattuordecillion +1E45 + + +Quindecillion +quindecillion +1E48 + + +Quintillion +quintillion +1E18 + + +Septendecillion +septendecillion +1E54 + + +Septillion +septillion +1E24 + + +Sexdecillion +sexdecillion +1E51 + + +Sextillion +sextillion +1E21 + + +Thousand +thousand +1E3 + + +Tredecillion +tredecillion +1E42 + + +Trillion +trillion +1E12 + + +Undecillion +undecillion +1E36 + + +Vigintillion +vigintillion +1E63 + + + +
+
+ +Physical Constants + +Atomic and Nuclear Constants + +Variables: Atomic and Nuclear Constants + + + + + + +Title +Names +Value + + + + +Alpha Particle Mass +alpha_particle_mass / m_α +6.6446565E-24*g (approximate) + + +Bohr Radius +bohr_radius / a_o +0.5291772108E-10*m (approximate) + + +Classical Electron Radius +classical_electron_radius / r_e +2.817940325E-15*m (approximate) + + +Compton Wavelength +compton_wavelength / λ_C +2.426310238E-12*m (approximate) + + +Electron Mass +electron_mass / m_e +9.1093826E-28*g (approximate) + + +Helion Mass +helion_mass / m_h +5.00641214E-24*g (approximate) + + +Neutron Mass +neutron_mass / m_n +1.67492728E-24*g (approximate) + + +Proton Mass +proton_mass / m_p +1.67262171E-24*g (approximate) + + +Rydberg Constant +rydberg / R_∞ +10973731.568525*m^(-1) (approximate) + + +Tau Mass +tau_mass / m_τ +3.16777E-24*g (approximate) + + + +
+
+ +Electromagnetic Constants + +Variables: Electromagnetic Constants + + + + + + +Title +Names +Value + + + + +Borh Magneton +bohr_magneton / μ_B +927.400949E-26*J*T^(-1) (approximate) + + +Conductance Quantum +conductance_quantum / G_0 +7.748091733E-5*S (approximate) + + +Elementary Charge +elementary_charge / e_charge +1.60217653E-19*C (approximate) + + +Josephson Constant +josephson / K_J +483597.879E9*Hz*V^(-1) (approximate) + + +Magnetic Flux Quantum +magnetic_flux_quantum / Φ_0 +2.06783372E-15*Wb (approximate) + + +Nuclear Magneton +nuclear_magneton / μ_N +5.05078343E-27*J*T^(-1) (approximate) + + +von Klitzing Constant +klitzing / R_K +25812.807449*ohm (approximate) + + + +
+
+ +Physico-Chemical Constants + +Variables: Physico-Chemical Constants + + + + + + +Title +Names +Value + + + + +Atomic Mass Constant +atomic_mass / m_u +1.66053886E-24*g (approximate) + + +Avogadro Constant +avogadro / N_A +6.0221415E23*mol^(-1) (approximate) + + +Boltzmann Constant +boltzmann +1.3806505E-23*J*K^(-1) (approximate) + + +Faraday Constant +faraday +96485.3383*C*mol^(-1) (approximate) + + +First Radiation Constant +first_radiation / c_1 +3.74177138E-16*W*m^2 (approximate) + + +Ideal Gas Constant +ideal_gas +8.314472*J*K^(-1)*mol^(-1) (approximate) + + +Second Radiation Constant +second_radiation / c_2 +1.4387752E-2*m*K (approximate) + + + +
+
+ +Universal Constants + +Variables: Universal Constants + + + + + + +Title +Names +Value + + + + +Characteristic Impedance of Vacuum +characteristic_impedance / Z_0 +4E-7*pi*299792458*ohm + + +Electric Constant (Permittivity of Free Space) +electric_constant / ε_0 +1/(4E-7*pi*299792458^2)*F*m^(-1) + + +Magnetic Constant (Permeability of Free Space) +magnetic_constant / μ_0 +4E-7*pi*N*A^(-2) + + +Newtonian Constant of Gravitation +newtonian_constant / G +6.6742E-11*m^3*kg^(-1)*s^(-2) (approximate) + + +Planck Constant +planck +6.6260693E-34*J*s (approximate) + + +Planck Constant over 2 pi +planck2pi +planck/(2*pi) + + +Planck Length +planck_length / l_P +1.61624E-35*m (approximate) + + +Planck Mass +planck_mass / m_P +2.17645E-5*g (approximate) + + +Planck Temperature +planck_temperature / T_P +1.41679E32*K (approximate) + + +Planck Time +planck_time / t_P +5.39121E-44*s (approximate) + + +Speed of Light in Vacuum +c / speed_of_light +299792458*m*s^(-1) + + + +
+
+
+ +Small Numbers + +Variables: Small Numbers + + + + + + +Title +Names +Value + + + + +Per Mille +permille / ‰ +1/1000 + + +Per Myriad +permyriad / ‱ +1/10000 + + +Procent +% / procent +1/100 + + + +
+
+ +Special Numbers + +Variables: Special Numbers + + + + + + +Title +Names +Value + + + + +False +false / no +0 + + +Imaginary i (sqrt -1) +i +i + + +Infinity +infinity +infinity + + +Negative Infinity +minus_infinity +-(+infinity) + + +Positive Infinity +plus_infinity +(+infinity) + + +True +true / yes +1 + + +Undefined +undefined +undefined + + + +
+
+ +Temporary + +Variables: Temporary + + + + + + +Title +Names +Value + + + + +Answer 2 +ans2 +a previous result + + +Answer 3 +ans3 +a previous result + + +Answer 4 +ans4 +a previous result + + +Answer 5 +ans5 +a previous result + + +Last Answer +ans / answer / ans1 +a previous result + + + +
+
+ +Unknowns + +Variables: Unknowns + + + + + + +Title +Names +Value + + + + +x +x +default assumptions + + +y +y +default assumptions + + +z +z +default assumptions + + + +
+
+ diff --git a/po/Makefile.am b/po/Makefile.am new file mode 100644 index 0000000..02dd0c1 --- /dev/null +++ b/po/Makefile.am @@ -0,0 +1,2 @@ +POFILES = AUTO + diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..8df6eef --- /dev/null +++ b/po/fr.po @@ -0,0 +1,2639 @@ +# translation of fr.po to Français +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# +# Nicolas Laug , 2006. +# Nicolas Laug , 2006. +msgid "" +msgstr "" +"Project-Id-Version: fr\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-05-08 14:44+0200\n" +"PO-Revision-Date: 2006-11-16 14:41-0500\n" +"Last-Translator: Nicolas Laug \n" +"Language-Team: Français \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" + +#: _translatorinfo.cpp:1 +msgid "" +"_: NAME OF TRANSLATORS\n" +"Your names" +msgstr "Nicolas Laug" + +#: _translatorinfo.cpp:3 +msgid "" +"_: EMAIL OF TRANSLATORS\n" +"Your emails" +msgstr "nicologmail-traduction@yahoo.fr" + +#: kqalculate.cpp:264 +msgid "Remove from System Tray" +msgstr "Enlever de la boîte à miniatures" + +#: kqalculate.cpp:265 qalculateeditdatasetdialog.cpp:471 +#: qalculateplotdialog.cpp:226 +msgid "Hide" +msgstr "Cacher" + +#: kqalculate.cpp:286 kqalculate.cpp:4484 kqalculate.cpp:5915 +msgid "Enter" +msgstr "Entrée" + +#: kqalculate.cpp:287 kqalculate.cpp:513 kqalculate.cpp:4485 +#: kqalculate.cpp:4492 kqalculate.cpp:5916 +msgid "=" +msgstr "=" + +#: kqalculate.cpp:289 kqalculate.cpp:514 kqalculate.cpp:4489 +#: kqalculate.cpp:4490 +msgid "Calculate expression and add to stack" +msgstr "Calculer l'expression et l'ajouter à la pile" + +#: kqalculate.cpp:290 kqalculate.cpp:515 kqalculate.cpp:4493 +#: kqalculate.cpp:4494 +msgid "Calculate expression" +msgstr "Calculer l'expression" + +#: kqalculate.cpp:296 kqalculate.cpp:5918 +msgid "Store" +msgstr "Enregistrer" + +#: kqalculate.cpp:298 +msgid "Store result as variable" +msgstr "Enregistrer le résultat dans une variable" + +#: kqalculate.cpp:301 kqalculate.cpp:5920 qalculateconvertunitsdialog.cpp:42 +msgid "Convert" +msgstr "Convertir" + +#: kqalculate.cpp:303 +msgid "Convert units in result" +msgstr "Changer les unités du résultat." + +#: kqalculate.cpp:313 +msgid "Enter expression here" +msgstr "Entrez une expression ici" + +#: kqalculate.cpp:322 +msgid "status" +msgstr "état" + +#: kqalculate.cpp:354 qalculateeditdataobjectdialog.cpp:71 +msgid "Exact" +msgstr "Exact" + +#: kqalculate.cpp:355 +msgid "Toggle exact mode" +msgstr "Basculer le mode exact" + +#: kqalculate.cpp:358 kqalculate.cpp:1070 +msgid "Fraction" +msgstr "Fraction" + +#: kqalculate.cpp:359 +msgid "Toggle fractional display" +msgstr "Basculer l'affichage en fraction" + +#: kqalculate.cpp:363 +msgid "Numerical display" +msgstr "Affichage numérique" + +#: kqalculate.cpp:366 kqalculate.cpp:1046 qalculateresultdisplay.cpp:288 +msgid "Normal" +msgstr "Normal" + +#: kqalculate.cpp:367 kqalculate.cpp:1048 qalculateresultdisplay.cpp:291 +msgid "Engineering" +msgstr "" + +#: kqalculate.cpp:368 kqalculate.cpp:1050 qalculateresultdisplay.cpp:294 +msgid "Scientific" +msgstr "Scientifique" + +#: kqalculate.cpp:369 +msgid "Pure" +msgstr "Pur" + +#: kqalculate.cpp:370 kqalculate.cpp:1054 +msgid "Simple" +msgstr "Simple" + +#: kqalculate.cpp:372 +msgid "Base in result" +msgstr "Base du résultat" + +#: kqalculate.cpp:376 kqalculate.cpp:1029 qalculatesetbasedialog.cpp:35 +#: qalculatesetbasedialog.cpp:48 +msgid "Binary" +msgstr "Binaire" + +#: kqalculate.cpp:377 kqalculate.cpp:1031 qalculatesetbasedialog.cpp:36 +#: qalculatesetbasedialog.cpp:49 +msgid "Octal" +msgstr "Octale" + +#: kqalculate.cpp:378 kqalculate.cpp:1033 kqalculate.cpp:1066 +#: qalculatesetbasedialog.cpp:37 qalculatesetbasedialog.cpp:50 +msgid "Decimal" +msgstr "Décimale" + +#: kqalculate.cpp:379 kqalculate.cpp:1035 qalculatesetbasedialog.cpp:38 +#: qalculatesetbasedialog.cpp:51 +msgid "Hexadecimal" +msgstr "Hexadécimale" + +#: kqalculate.cpp:380 kqalculate.cpp:1039 qalculatesetbasedialog.cpp:42 +msgid "Sexagesimal" +msgstr "Sexagésimale" + +#: kqalculate.cpp:381 kqalculate.cpp:1041 +msgid "Time Format" +msgstr "Format de l'heure" + +#: kqalculate.cpp:383 kqalculate.cpp:1037 +msgid "Other..." +msgstr "Autre..." + +#: kqalculate.cpp:389 +msgid "f(x)" +msgstr "f(x)" + +#: kqalculate.cpp:393 +msgid "Open functions manager" +msgstr "Ouvrir le gestionnaire de fonctions" + +#: kqalculate.cpp:395 +msgid "sqrt" +msgstr "sqrt" + +#: kqalculate.cpp:396 +msgid "Square root" +msgstr "Racine carrée" + +#: kqalculate.cpp:399 kqalculate.cpp:947 +msgid "xy" +msgstr "xy" + +#: kqalculate.cpp:400 +msgid "Raise (Ctrl+*)" +msgstr "Élever (Ctrl+*)" + +#: kqalculate.cpp:403 kqalculate.cpp:946 +msgid "x2" +msgstr "x2" + +#: kqalculate.cpp:404 +msgid "Square" +msgstr "Carré" + +#: kqalculate.cpp:406 +msgid "log" +msgstr "log" + +#: kqalculate.cpp:407 +msgid "Base-10 logarithm" +msgstr "Logarithme en base 10" + +#: kqalculate.cpp:409 +msgid "ln" +msgstr "ln" + +#: kqalculate.cpp:410 +msgid "Natural logarithm" +msgstr "Logarithme népérien (naturel)" + +#: kqalculate.cpp:412 +msgid "x!" +msgstr "x!" + +#: kqalculate.cpp:413 +msgid "Factorial" +msgstr "Factorielle" + +#: kqalculate.cpp:415 +msgid "cos" +msgstr "cos" + +#: kqalculate.cpp:416 +msgid "Cosine" +msgstr "Cosinus" + +#: kqalculate.cpp:418 +msgid "tan" +msgstr "tan" + +#: kqalculate.cpp:419 +msgid "Tangent" +msgstr "Tangente" + +#: kqalculate.cpp:421 +msgid "hyp" +msgstr "hyp" + +#: kqalculate.cpp:422 +msgid "Toggle hyperbolic functions" +msgstr "Basculer les fonctions hyperboliques" + +#: kqalculate.cpp:425 +msgid "inv" +msgstr "inv" + +#: kqalculate.cpp:426 +msgid "Toggle inverse functions" +msgstr "Basculer les fonctions réciproques" + +#: kqalculate.cpp:429 +msgid "sin" +msgstr "sin" + +#: kqalculate.cpp:430 +msgid "Sine" +msgstr "Sinus" + +#: kqalculate.cpp:435 +msgid "Deg" +msgstr "Deg" + +#: kqalculate.cpp:436 +msgid "Angle Unit: Degrees" +msgstr "Unité d'angle : Degré" + +#: kqalculate.cpp:439 +msgid "Rad" +msgstr "Rad" + +#: kqalculate.cpp:440 +msgid "Angle Unit: Radians" +msgstr "Unité d'angle : Radian" + +#: kqalculate.cpp:443 +msgid "Gra" +msgstr "Gr" + +#: kqalculate.cpp:444 +msgid "Angle Unit: Gradians" +msgstr "Unité d'angle : Grade" + +#: kqalculate.cpp:447 kqalculate.cpp:1094 kqalculate.cpp:1152 +#: qalculateplotdialog.cpp:126 +msgid "None" +msgstr "Aucun" + +#: kqalculate.cpp:464 +msgid "7" +msgstr "7" + +#: kqalculate.cpp:466 +msgid "8" +msgstr "8" + +#: kqalculate.cpp:468 +msgid "9" +msgstr "9" + +#: kqalculate.cpp:470 +msgid "4" +msgstr "4" + +#: kqalculate.cpp:472 +msgid "5" +msgstr "5" + +#: kqalculate.cpp:474 +msgid "6" +msgstr "6" + +#: kqalculate.cpp:476 +msgid "1" +msgstr "1" + +#: kqalculate.cpp:478 +msgid "2" +msgstr "2" + +#: kqalculate.cpp:480 +msgid "3" +msgstr "3" + +#: kqalculate.cpp:482 +msgid "0" +msgstr "0" + +#: kqalculate.cpp:485 +msgid "Decimal point" +msgstr "Point décimal" + +#: kqalculate.cpp:487 +msgid "EXP" +msgstr "EXP" + +#: kqalculate.cpp:488 +msgid "10^x (Ctrl+Shift+E)" +msgstr "" + +#: kqalculate.cpp:491 +msgid "Del" +msgstr "Eff" + +#: kqalculate.cpp:494 +msgid "AC" +msgstr "AC" + +#: kqalculate.cpp:498 +msgid "Multiply" +msgstr "Multiplier" + +#: kqalculate.cpp:501 +msgid "Divide" +msgstr "Diviser" + +#: kqalculate.cpp:507 +msgid "Subtract" +msgstr "Soustraire" + +#: kqalculate.cpp:509 +msgid "Ans" +msgstr "Préc." + +#: kqalculate.cpp:510 +msgid "Previous result" +msgstr "Résultat précédent" + +#: kqalculate.cpp:512 kqalculate.cpp:4488 +msgid "Ent" +msgstr "Ent" + +#: kqalculate.cpp:535 +msgid "Index" +msgstr "Index" + +#: kqalculate.cpp:536 qalculateeditdataobjectdialog.cpp:49 +#: qalculatevariablesdialog.cpp:61 +msgid "Value" +msgstr "Valeur" + +#: kqalculate.cpp:555 kqalculate.cpp:5924 +msgid "Up" +msgstr "Haut" + +#: kqalculate.cpp:556 +msgid "Move selected register up" +msgstr "Déplacer le registre sélectionné vers le haut" + +#: kqalculate.cpp:560 kqalculate.cpp:5926 +msgid "Down" +msgstr "Bas" + +#: kqalculate.cpp:561 +msgid "Move selected register down" +msgstr "Déplacer le registre sélectionné vers le bas" + +#: kqalculate.cpp:566 +msgid "Edit value of selected register" +msgstr "Éditer la valeur du registre sélectionné" + +#: kqalculate.cpp:571 +msgid "Delete selected register" +msgstr "Effacer le registre sélectionné" + +#: kqalculate.cpp:576 +msgid "Clear the RPN stack" +msgstr "Vider la pile NPI" + +#: kqalculate.cpp:592 +msgid "Keypad" +msgstr "Clavier" + +#: kqalculate.cpp:593 +msgid "Show/hide keypad" +msgstr "Afficher/cacher le clavier" + +#: kqalculate.cpp:596 +msgid "History" +msgstr "Historique" + +#: kqalculate.cpp:597 +msgid "Show/hide history" +msgstr "Afficher/Cacher l'historique" + +#: kqalculate.cpp:600 +msgid "RPN Stack" +msgstr "Pile NPI" + +#: kqalculate.cpp:601 +msgid "Show/hide RPN stack" +msgstr "Afficher/Cacher la pile NPI" + +#: kqalculate.cpp:716 kqalculate.cpp:2527 +msgid "RPN Register Moved" +msgstr "Registre NPI déplacé" + +#: kqalculate.cpp:752 kqalculate.cpp:784 kqalculate.cpp:2138 +#: kqalculate.cpp:2702 kqalculate.cpp:2739 +msgid "approx." +msgstr "approx." + +#: kqalculate.cpp:894 kqalculate.cpp:4813 +msgid "Load meta mode: %1" +msgstr "" + +#: kqalculate.cpp:966 +msgid "Qalculate! - Scientific Calculator" +msgstr "Qalculate! - Caculatrice Scientifique" + +#: kqalculate.cpp:985 qalculateeditfunctiondialog.cpp:601 +#: qalculateresultdisplay.cpp:62 +msgid "Variable" +msgstr "Variable" + +#: kqalculate.cpp:986 qalculateeditfunctiondialog.cpp:596 +#: qalculateeditmatrixvectordialog.cpp:106 qalculateimportcsvdialog.cpp:52 +#: qalculateinsertmatrixvectordialog.cpp:85 +#: qalculateinsertmatrixvectordialog.cpp:310 +msgid "Matrix" +msgstr "Matrice" + +#: kqalculate.cpp:987 qalculateeditfunctiondialog.cpp:595 +#: qalculateeditmatrixvectordialog.cpp:109 +#: qalculateinsertmatrixvectordialog.cpp:88 +#: qalculateinsertmatrixvectordialog.cpp:308 +msgid "Vector" +msgstr "Vecteur" + +#: kqalculate.cpp:988 +msgid "Unknown Variable" +msgstr "Variable Inconnue" + +#: kqalculate.cpp:989 qalculateeditdatasetdialog.cpp:70 +#: qalculateeditfunctiondialog.cpp:71 qalculateeditfunctiondialog.cpp:599 +#: qalculateplotdialog.cpp:98 qalculateresultdisplay.cpp:92 +msgid "Function" +msgstr "Fonction" + +#: kqalculate.cpp:990 qalculatedatasetsdialog.cpp:64 +msgid "Data Set" +msgstr "Ensemble de données" + +#: kqalculate.cpp:991 qalculateconvertunitsdialog.cpp:68 +#: qalculateeditfunctiondialog.cpp:600 qalculateresultdisplay.cpp:67 +#: qalculateunitsdialog.cpp:67 +msgid "Unit" +msgstr "Unité" + +#: kqalculate.cpp:992 +msgid "Import CSV File..." +msgstr "Importer un fichier CSV..." + +#: kqalculate.cpp:993 +msgid "Export CSV File..." +msgstr "Exporter un fichier CSV..." + +#: kqalculate.cpp:994 +msgid "Store Result..." +msgstr "Enregistrer le résultat..." + +#: kqalculate.cpp:995 +msgid "Save Result Image..." +msgstr "Enregistrer l'image du résultat..." + +#: kqalculate.cpp:996 +msgid "Save Definitions" +msgstr "Enregistrer les définitions" + +#: kqalculate.cpp:997 +msgid "Update Exchange Rates" +msgstr "Mettre à jour les taux d'échange" + +#: kqalculate.cpp:998 +msgid "Plot Functions/Data" +msgstr "Tracer des fonctions/données" + +#: kqalculate.cpp:1000 +msgid "Convert Number Bases" +msgstr "Convertir des bases de nombres" + +#: kqalculate.cpp:1001 qalculateperiodictabledialog.cpp:40 +msgid "Periodic Table" +msgstr "Table périodique" + +#: kqalculate.cpp:1008 +msgid "Show/hide main Qalculate! window" +msgstr "" + +#: kqalculate.cpp:1011 +#, fuzzy +msgid "Configure &Global Shortcuts..." +msgstr "Configurer Qalculate!" + +#: kqalculate.cpp:1013 +msgid "Manage Variables" +msgstr "Gérer les variables" + +#: kqalculate.cpp:1014 +msgid "Manage Functions" +msgstr "Gérer les fonctions" + +#: kqalculate.cpp:1015 +msgid "Manage Units" +msgstr "Gérer les unités" + +#: kqalculate.cpp:1016 +msgid "Manage Data Sets" +msgstr "Gérer les ensembles de données" + +#: kqalculate.cpp:1017 kqalculate.cpp:1150 +msgid "Factorize" +msgstr "Factoriser" + +#: kqalculate.cpp:1018 kqalculate.cpp:1148 +msgid "Simplify" +msgstr "Simplifier" + +#: kqalculate.cpp:1019 +msgid "Set Unknowns..." +msgstr "Définir les inconnues..." + +#: kqalculate.cpp:1020 +msgid "Convert to Unit Expression..." +msgstr "Convertir en expression d'unités..." + +#: kqalculate.cpp:1021 kqalculate.cpp:1084 +msgid "Convert to Base Units" +msgstr "Convertir en unités de base" + +#: kqalculate.cpp:1022 kqalculate.cpp:1086 +msgid "Convert to Best Unit" +msgstr "Convertir vers la meilleure unité" + +#: kqalculate.cpp:1023 +msgid "Insert Matrix..." +msgstr "Insérer une matrice..." + +#: kqalculate.cpp:1024 +msgid "Insert Vector..." +msgstr "Insérer un vecteur" + +#: kqalculate.cpp:1025 +msgid "Copy Result" +msgstr "Copier le résultat" + +#: kqalculate.cpp:1026 +msgid "Clear History" +msgstr "Vider l'historique" + +#: kqalculate.cpp:1027 +msgid "Configure Qalculate!" +msgstr "Configurer Qalculate!" + +#: kqalculate.cpp:1043 +msgid "Roman Numerals" +msgstr "Chiffres romains" + +#: kqalculate.cpp:1045 +msgid "Select Result and Expression Base..." +msgstr "Sélectionner la base du résultat et de l'expression..." + +#: kqalculate.cpp:1052 +msgid "Purely Scientific" +msgstr "Purement scientifique" + +#: kqalculate.cpp:1056 +msgid "Indicate Infinite Series" +msgstr "Indiquer les suites infinies" + +#: kqalculate.cpp:1058 +msgid "Sort Minus Last" +msgstr "" + +#: kqalculate.cpp:1060 +#, fuzzy +msgid "Negative Exponents" +msgstr "Strictement négatif" + +#: kqalculate.cpp:1062 +msgid "Show Ending Zeroes" +msgstr "Afficher les zéros de fin" + +#: kqalculate.cpp:1064 +msgid "Round Halfway Numbers to Even" +msgstr "Arrondir les nombres à mi-chemin au nombre inférieur" + +#: kqalculate.cpp:1068 +msgid "Decimal (Try Exact)" +msgstr "Décimal (essayer exact)" + +#: kqalculate.cpp:1072 +msgid "Combined" +msgstr "Combiné" + +#: kqalculate.cpp:1074 +msgid "Enable Prefixes" +msgstr "Activer les préfixes" + +#: kqalculate.cpp:1076 +msgid "Enable Use of All SI Prefixes" +msgstr "Activer l'utilisation de tous les préfixes SI" + +#: kqalculate.cpp:1078 +msgid "Enable Denominator Prefixes" +msgstr "Activer les préfixes de dénominateur" + +#: kqalculate.cpp:1080 +msgid "Place Units Separately" +msgstr "Placer les unités séparément" + +#: kqalculate.cpp:1082 +msgid "No Automatic Conversion" +msgstr "Pas de conversion automatique" + +#: kqalculate.cpp:1088 +msgid "Degrees" +msgstr "Dégrés" + +#: kqalculate.cpp:1090 +msgid "Radians" +msgstr "Radians" + +#: kqalculate.cpp:1092 +msgid "Gradians" +msgstr "Grades" + +#: kqalculate.cpp:1096 +msgid "Abbreviate Names" +msgstr "Noms abrégés" + +#: kqalculate.cpp:1098 +msgid "Enable Variables" +msgstr "Activer les variables" + +#: kqalculate.cpp:1100 +msgid "Enable Functions" +msgstr "Activer les fonctions" + +#: kqalculate.cpp:1102 +msgid "Enable Units" +msgstr "Activer les unités" + +#: kqalculate.cpp:1104 +msgid "Enable Unknowns" +msgstr "Activer les inconnues" + +#: kqalculate.cpp:1106 +msgid "Calculate Variables" +msgstr "Calculer les variables" + +#: kqalculate.cpp:1108 +msgid "Allow Complex Result" +msgstr "Autoriser les résultats complexes" + +#: kqalculate.cpp:1110 +msgid "Allow Infinite Result" +msgstr "Autoriser les résultats infinis" + +#: kqalculate.cpp:1112 +msgid "Try Exact" +msgstr "Essayer les résultats exacts" + +#: kqalculate.cpp:1114 +msgid "Always Exact" +msgstr "Toujours exact" + +#: kqalculate.cpp:1116 qalculateeditdataobjectdialog.cpp:70 +msgid "Approximate" +msgstr "Approximer" + +#: kqalculate.cpp:1118 kqalculate.cpp:1132 +#: qalculateeditunknownvariabledialog.cpp:65 +#: qalculateeditunknownvariabledialog.cpp:78 +#: qalculateperiodictabledialog.cpp:235 +msgid "Unknown" +msgstr "Inconnue" + +#: kqalculate.cpp:1120 qalculateeditunknownvariabledialog.cpp:66 +msgid "Not Matrix" +msgstr "Non matriciel" + +#: kqalculate.cpp:1122 qalculateeditdatasetdialog.cpp:468 +#: qalculateeditfunctiondialog.cpp:590 +#: qalculateeditunknownvariabledialog.cpp:67 +msgid "Number" +msgstr "Nombre" + +#: kqalculate.cpp:1124 +msgid "Complex" +msgstr "Complexe" + +#: kqalculate.cpp:1126 +msgid "Real" +msgstr "Réel" + +#: kqalculate.cpp:1128 +msgid "Rational" +msgstr "Rationnel" + +#: kqalculate.cpp:1130 qalculateeditfunctiondialog.cpp:591 +#: qalculateeditunknownvariabledialog.cpp:71 +msgid "Integer" +msgstr "Entier" + +#: kqalculate.cpp:1134 qalculateeditunknownvariabledialog.cpp:83 +msgid "Non-Zero" +msgstr "Non nul" + +#: kqalculate.cpp:1136 qalculateeditunknownvariabledialog.cpp:79 +msgid "Positive" +msgstr "Strictement positif" + +#: kqalculate.cpp:1138 qalculateeditunknownvariabledialog.cpp:80 +msgid "Non-Negative" +msgstr "Positif" + +#: kqalculate.cpp:1140 qalculateeditunknownvariabledialog.cpp:81 +msgid "Negative" +msgstr "Strictement négatif" + +#: kqalculate.cpp:1142 qalculateeditunknownvariabledialog.cpp:82 +msgid "Non-Positive" +msgstr "Négatif" + +#: kqalculate.cpp:1144 +msgid "Non-Zero Denominators" +msgstr "Dénominateurs non nuls" + +#: kqalculate.cpp:1146 +msgid "Warn About Denominators Assumed Non-Zero" +msgstr "Alerter si les dénominateurs sont supposés non nuls" + +#: kqalculate.cpp:1154 +msgid "Read Precision" +msgstr "Précision de la saisie" + +#: kqalculate.cpp:1156 +msgid "Limit Implicit Multiplication" +msgstr "Limiter les multiplications implicites" + +#: kqalculate.cpp:1158 +msgid "RPN Mode" +msgstr "Mode NPI" + +#: kqalculate.cpp:1160 +msgid "RPN Syntax" +msgstr "Syntaxe NPI" + +#: kqalculate.cpp:1162 qalculateprecisiondialog.cpp:31 +msgid "Precision" +msgstr "Précision" + +#: kqalculate.cpp:1163 qalculatedecimalsdialog.cpp:27 +msgid "Decimals" +msgstr "Décimales" + +#: kqalculate.cpp:1164 +msgid "Save Mode..." +msgstr "Enregistrer le mode..." + +#: kqalculate.cpp:1165 +msgid "Delete Mode..." +msgstr "Effacer le mode" + +#: kqalculate.cpp:1167 +msgid "Save Default Mode" +msgstr "Enregistrer le mode par défaut" + +#: kqalculate.cpp:1168 +msgid "Clear Stack" +msgstr "Vider la pile" + +#: kqalculate.cpp:1172 +#, fuzzy +msgid "Exp RPN Operation" +msgstr "Opération NPI" + +#: kqalculate.cpp:1860 +msgid "and" +msgstr "et" + +#: kqalculate.cpp:1865 +msgid "or" +msgstr "ou" + +#: kqalculate.cpp:2122 +msgid "undefined" +msgstr "indéfini" + +#: kqalculate.cpp:2164 +msgid "EXACT" +msgstr "EXACT" + +#: kqalculate.cpp:2167 +msgid "APPROX" +msgstr "APPROX" + +#: kqalculate.cpp:2171 +msgid "RPN" +msgstr "NPI" + +#: kqalculate.cpp:2179 +msgid "BIN" +msgstr "BIN" + +#: kqalculate.cpp:2184 +msgid "OCT" +msgstr "OCT" + +#: kqalculate.cpp:2189 +msgid "HEX" +msgstr "HEX" + +#: kqalculate.cpp:2194 +msgid "ROMAN" +msgstr "ROMAIN" + +#: kqalculate.cpp:2206 +msgid "DEG" +msgstr "DEG" + +#: kqalculate.cpp:2211 +msgid "RAD" +msgstr "RAD" + +#: kqalculate.cpp:2216 +msgid "GRA" +msgstr "GR" + +#: kqalculate.cpp:2223 +msgid "PREC" +msgstr "PREC" + +#: kqalculate.cpp:2228 +msgid "FUNC" +msgstr "FUNC" + +#: kqalculate.cpp:2234 +msgid "UNIT" +msgstr "UNIT" + +#: kqalculate.cpp:2240 +msgid "VAR" +msgstr "VAR" + +#: kqalculate.cpp:2246 +msgid "INF" +msgstr "INF" + +#: kqalculate.cpp:2252 +msgid "CPLX" +msgstr "CPLX" + +#: kqalculate.cpp:2333 kqalculate.cpp:2351 kqalculate.cpp:2581 +msgid "aborted" +msgstr "abandonné" + +#: kqalculate.cpp:2352 +msgid "calculation was aborted" +msgstr "le calcul a été abandonné" + +#: kqalculate.cpp:2588 +msgid "result processing was aborted" +msgstr "le calcul du résultat a été abandonné" + +#: kqalculate.cpp:2636 +msgid "Processing..." +msgstr "Calcul en cours..." + +#: kqalculate.cpp:2640 kqalculate.cpp:2885 kqalculate.cpp:3145 +msgid "Abort" +msgstr "Abandonner" + +#: kqalculate.cpp:2873 +msgid "Factorizing..." +msgstr "Factorisation en cours..." + +#: kqalculate.cpp:2877 +msgid "Simplifying..." +msgstr "Simplification en cours..." + +#: kqalculate.cpp:3141 +msgid "Calculating..." +msgstr "Calcul en cours..." + +#: kqalculate.cpp:3191 +msgid "RPN Operation" +msgstr "Opération NPI" + +#: kqalculate.cpp:3259 +msgid "Errors" +msgstr "Erreurs" + +#: kqalculate.cpp:3260 +msgid "Warnings" +msgstr "Avertissements" + +#: kqalculate.cpp:3270 +msgid "Couldn't write definitions" +msgstr "Impossible d'écrire les définitions" + +#: kqalculate.cpp:3538 +msgid "Prefixes" +msgstr "Préfixes" + +#: kqalculate.cpp:3665 +msgid "No Prefix" +msgstr "Pas de préfixe" + +#: kqalculate.cpp:3816 qalculatevariablesdialog.cpp:191 +#: qalculatevariablesdialog.cpp:337 +msgid "Variable does not exist anymore." +msgstr "La variable n'existe plus" + +#: kqalculate.cpp:3832 qalculateconvertunitsdialog.cpp:153 +#: qalculateunitsdialog.cpp:223 qalculateunitsdialog.cpp:337 +msgid "Unit does not exist anymore." +msgstr "L'unité n'existe plus" + +#: kqalculate.cpp:3905 +msgid "Failed to download exchange rates from ECB." +msgstr "Échec du téléchargement des taux d'échanges de ECB." + +#: kqalculate.cpp:4752 +msgid "Save Mode" +msgstr "Enregister le mode" + +#: kqalculate.cpp:4755 +#, fuzzy +msgid "Mode name:" +msgstr "Nom du Mode:" + +#: kqalculate.cpp:4765 +msgid "Shortcut:" +msgstr "" + +#: kqalculate.cpp:4792 +msgid "Empty mode name." +msgstr "Nom de mode vide." + +#: kqalculate.cpp:4795 +msgid "Preset mode cannot be overwritten." +msgstr "La prédéfinition ne peut être écrasée." + +#: kqalculate.cpp:4827 +msgid "Delete Mode" +msgstr "Effacer le mode" + +#: kqalculate.cpp:4827 +msgid "Mode:" +msgstr "Mode:" + +#: kqalculate.cpp:5001 +msgid "log10 function not found." +msgstr "Fonction log10 non trouvée." + +#: kqalculate.cpp:5545 main.cpp:156 main.cpp:159 main.cpp:160 main.cpp:161 +#: main.cpp:162 +msgid "Temporary" +msgstr "Temporaire" + +#: kqalculate.cpp:5567 kqalculate.cpp:5594 qalculatefunctionsdialog.cpp:191 +#: qalculatefunctionsdialog.cpp:300 +msgid "Function does not exist anymore." +msgstr "La fonction n'existe plus." + +#: kqalculate.cpp:5697 kqalculate.cpp:5733 +msgid "My Variables" +msgstr "Mes variables" + +#: kqalculate.cpp:5709 qalculateimportcsvdialog.cpp:56 +msgid "Vectors" +msgstr "Vecteurs" + +#: kqalculate.cpp:5721 +msgid "Matrices" +msgstr "Matrices" + +#: kqalculate.cpp:5762 qalculateplotdialog.cpp:726 +msgid "Save Image" +msgstr "Enregistrer l'image" + +#: kqalculate.cpp:5767 qalculateplotdialog.cpp:731 +msgid "" +"A file named \"%1\" already exists. Are you sure you want to overwrite it?" +msgstr "" +"Un fichier nommé \"%1\" existe déjà. Êtes-vous sûr de vouloir l'écraser?" + +#: kqalculate.cpp:5767 qalculateplotdialog.cpp:731 +msgid "Overwrite File?" +msgstr "Écraser le fichier?" + +#: kqalculate.cpp:5767 qalculateplotdialog.cpp:731 +msgid "&Overwrite" +msgstr "&Écraser" + +#: kqalculate.cpp:5801 +msgid "Failed to save image." +msgstr "Échec de l'enregistrement de l'image." + +#: kqalculate.cpp:6027 +msgid "No unknowns in result." +msgstr "Pas d'inconnue dans le résultat." + +#: kqalculate.cpp:6030 +msgid "Set Unknowns" +msgstr "Définir les inconnues" + +#: kqalculate.cpp:6194 +msgid "Too many arguments for %1()." +msgstr "Trop d'arguments pour %1()." + +#: kqalculate.cpp:6220 qalculatedatasetsdialog.cpp:342 +#: qalculatefunctionsdialog.cpp:343 qalculateresultdisplay.cpp:120 +msgid "argument" +msgstr "argument" + +#: kqalculate.cpp:6442 kqalculate.cpp:6446 +#, fuzzy +msgid "Edit Expression" +msgstr "Expression" + +#: kqalculate.cpp:6451 +#, fuzzy +msgid "Edit Result" +msgstr "Éditer les noms" + +#: kqalculate.cpp:6454 +#, fuzzy +msgid "Insert Result Variable" +msgstr "Enregistrer le résultat dans une variable" + +#: main.cpp:45 +msgid "A powerful and easy to use desktop calculator" +msgstr "Une calculatrice de bureau puissante et facile à utiliser" + +#: main.cpp:51 +msgid "Calculate X11-clipboard content (selected text)" +msgstr "Caculer le contenu du presse papier de X11 (texte sélectionné)" + +#: main.cpp:52 +msgid "Initial expression to calculate" +msgstr "Expression initiale à calculer" + +#: main.cpp:134 +msgid "Enter a mathematical expression above.
Ex. 5 + 2 / 3" +msgstr "Entrez une expression mathématique ci-dessous.
Ex. 5 + 2 / 3" + +#: main.cpp:143 +msgid "" +"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" +"\n" +"Do you want to fetch exchange rates now from the Internet?" +msgstr "" +"Vous devez télécharger les taux d'échange pour effectuer des conversions " +"entre différentes devises. Vous pourrez ensuite récupérer les taux d'échange " +"en sélectionnant\"Mettre à jour les taux d'échange\" dans le menu Fichier.\n" +"\n" +"Voulez-vous télécharger les taux d'échange sur Internet maintenant?" + +#: main.cpp:143 +msgid "Update exchange rates?" +msgstr "Mettre à jour les taux d'échange?" + +#: main.cpp:155 +msgid "ans" +msgstr "ans" + +#: main.cpp:156 +msgid "Last Answer" +msgstr "Réponse précédente" + +#: main.cpp:157 +msgid "answer" +msgstr "réponse" + +#: main.cpp:159 +msgid "Answer 2" +msgstr "Réponse 2" + +#: main.cpp:160 +msgid "Answer 3" +msgstr "Réponse 3" + +#: main.cpp:161 +msgid "Answer 4" +msgstr "Réponse 4" + +#: main.cpp:162 +msgid "Answer 5" +msgstr "Réponse 5" + +#: main.cpp:166 +msgid "Failed to load global definitions!" +msgstr "Échec du chargement des définitions globales!" + +#: main.cpp:290 +msgid "Qalculate!" +msgstr "Qalculate!" + +#: preferences.cpp:208 +msgid "Preset" +msgstr "Présélection" + +#: preferences.cpp:669 +#, c-format +msgid "" +"Couldn't write preferences to\n" +"%s" +msgstr "Impossible d'écrire les préférences sur
%s" + +#: qalculateconvertnumberbasesdialog.cpp:31 qalculatesetbasedialog.cpp:29 +msgid "Number Bases" +msgstr "Bases numériques" + +#: qalculateconvertnumberbasesdialog.cpp:37 +msgid "Decimal:" +msgstr "Décimale:" + +#: qalculateconvertnumberbasesdialog.cpp:41 +msgid "Binary:" +msgstr "Binaire:" + +#: qalculateconvertnumberbasesdialog.cpp:45 +msgid "Octal:" +msgstr "Octale:" + +#: qalculateconvertnumberbasesdialog.cpp:49 +msgid "Hexadecimal:" +msgstr "Hexadécimale:" + +#: qalculateconvertunitsdialog.cpp:44 +msgid "Selector" +msgstr "Sélecteur" + +#: qalculateconvertunitsdialog.cpp:50 qalculateeditdatasetdialog.cpp:482 +msgid "Unit expression:" +msgstr "Expression d'unités:" + +#: qalculateconvertunitsdialog.cpp:63 qalculatefunctionsdialog.cpp:55 +#: qalculateunitsdialog.cpp:63 qalculatevariablesdialog.cpp:57 +msgid "Category" +msgstr "Catégorie" + +#: qalculateconvertunitsdialog.cpp:85 qalculateconvertunitsdialog.cpp:86 +#: qalculateconvertunitsdialog.cpp:141 qalculateconvertunitsdialog.cpp:180 +#: qalculatefunctionsdialog.cpp:118 qalculatefunctionsdialog.cpp:119 +#: qalculatefunctionsdialog.cpp:183 qalculatefunctionsdialog.cpp:505 +#: qalculateunitsdialog.cpp:150 qalculateunitsdialog.cpp:151 +#: qalculateunitsdialog.cpp:215 qalculateunitsdialog.cpp:416 +#: qalculatevariablesdialog.cpp:116 qalculatevariablesdialog.cpp:117 +#: qalculatevariablesdialog.cpp:183 qalculatevariablesdialog.cpp:462 +msgid "All" +msgstr "Tous" + +#: qalculateconvertunitsdialog.cpp:132 qalculateconvertunitsdialog.cpp:133 +#: qalculateconvertunitsdialog.cpp:134 qalculateconvertunitsdialog.cpp:182 +#: qalculatefunctionsdialog.cpp:165 qalculatefunctionsdialog.cpp:166 +#: qalculatefunctionsdialog.cpp:167 qalculatefunctionsdialog.cpp:236 +#: qalculatefunctionsdialog.cpp:262 qalculatefunctionsdialog.cpp:285 +#: qalculatefunctionsdialog.cpp:507 qalculateunitsdialog.cpp:197 +#: qalculateunitsdialog.cpp:198 qalculateunitsdialog.cpp:199 +#: qalculateunitsdialog.cpp:273 qalculateunitsdialog.cpp:299 +#: qalculateunitsdialog.cpp:322 qalculateunitsdialog.cpp:418 +#: qalculatevariablesdialog.cpp:165 qalculatevariablesdialog.cpp:166 +#: qalculatevariablesdialog.cpp:167 qalculatevariablesdialog.cpp:258 +#: qalculatevariablesdialog.cpp:284 qalculatevariablesdialog.cpp:322 +#: qalculatevariablesdialog.cpp:464 +msgid "Uncategorized" +msgstr "Sans catégorie" + +#: qalculatedatasetsdialog.cpp:46 qalculateeditdatasetdialog.cpp:232 +msgid "Data Sets" +msgstr "Ensembles de données" + +#: qalculatedatasetsdialog.cpp:61 +msgid "Data Sets:" +msgstr "Ensembles de données:" + +#: qalculatedatasetsdialog.cpp:68 qalculatedatasetsdialog.cpp:91 +#: qalculateeditdatasetdialog.cpp:107 qalculateeditdatasetdialog.cpp:629 +#: qalculateeditfunctiondialog.cpp:133 qalculateeditfunctiondialog.cpp:492 +#: qalculateeditnamesdialog.cpp:64 qalculatefunctionsdialog.cpp:67 +#: qalculateunitsdialog.cpp:91 qalculatevariablesdialog.cpp:66 +msgid "New" +msgstr "Nouveau" + +#: qalculatedatasetsdialog.cpp:77 qalculateeditdatasetdialog.cpp:79 +#: qalculateeditdatasetdialog.cpp:456 qalculateeditfunctiondialog.cpp:98 +msgid "Description:" +msgstr "Description:" + +#: qalculatedatasetsdialog.cpp:84 +msgid "Objects:" +msgstr "Objets:" + +#: qalculatedatasetsdialog.cpp:87 qalculateeditdatasetdialog.cpp:236 +#: qalculateeditfunctiondialog.cpp:598 +msgid "Object" +msgstr "Objet" + +#: qalculatedatasetsdialog.cpp:100 +msgid "Attributes:" +msgstr "Attributs:" + +#: qalculatedatasetsdialog.cpp:157 qalculatedatasetsdialog.cpp:218 +msgid "Data set does not exist anymore." +msgstr "L'ensemble de données n'existe plus." + +#: qalculatedatasetsdialog.cpp:300 qalculateeditdatasetdialog.cpp:195 +#: qalculatefunctionsdialog.cpp:456 +msgid "key" +msgstr "clé" + +#: qalculatedatasetsdialog.cpp:316 +msgid "Data Retrieval Function" +msgstr "Fonction de récupération de données" + +#: qalculatedecimalsdialog.cpp:31 +msgid "Max decimals:" +msgstr "Décimales max:" + +#: qalculatedecimalsdialog.cpp:39 +msgid "Min decimals:" +msgstr "Décimales min:" + +#: qalculateeditdataobjectdialog.cpp:30 qalculateeditdataobjectdialog.cpp:40 +msgid "Edit Object" +msgstr "Éditer l'objet" + +#: qalculateeditdataobjectdialog.cpp:42 +msgid "New Object" +msgstr "Nouvel objet" + +#: qalculateeditdataobjectdialog.cpp:48 qalculateeditdatasetdialog.cpp:242 +msgid "Property" +msgstr "Propriété" + +#. i18n: file ./qalculate_kdeui.rc line 116 +#: qalculateeditdataobjectdialog.cpp:51 rc.cpp:39 +#, no-c-format +msgid "Approximation" +msgstr "Approximation" + +#: qalculateeditdatasetdialog.cpp:53 qalculateeditdatasetdialog.cpp:307 +msgid "Edit Data Set" +msgstr "Éditer l'ensemble de données" + +#: qalculateeditdatasetdialog.cpp:68 qalculateeditfunctiondialog.cpp:70 +#: qalculatepreferencesdialog.cpp:157 +msgid "General" +msgstr "Général" + +#: qalculateeditdatasetdialog.cpp:73 qalculateplotdialog.cpp:86 +#: qalculateplotdialog.cpp:189 +msgid "Title:" +msgstr "Titre:" + +#: qalculateeditdatasetdialog.cpp:76 +msgid "Data file:" +msgstr "Fichier de données:" + +#: qalculateeditdatasetdialog.cpp:87 +msgid "Copyright:" +msgstr "Copyright:" + +#: qalculateeditdatasetdialog.cpp:97 +msgid "Properties:" +msgstr "Propriétés:" + +#: qalculateeditdatasetdialog.cpp:99 qalculateplotdialog.cpp:153 +msgid "Title" +msgstr "Titre" + +#: qalculateeditdatasetdialog.cpp:100 qalculateeditdatasetdialog.cpp:620 +#: qalculateeditfunctiondialog.cpp:124 qalculateeditnamesdialog.cpp:41 +#: qalculateeditunitdialog.cpp:50 +msgid "Name" +msgstr "Nom" + +#: qalculateeditdatasetdialog.cpp:101 qalculateeditfunctiondialog.cpp:125 +#: qalculateeditunitdialog.cpp:75 qalculateeditunknownvariabledialog.cpp:60 +msgid "Type" +msgstr "Type" + +#: qalculateeditdatasetdialog.cpp:115 qalculateeditdatasetdialog.cpp:442 +#: qalculateeditfunctiondialog.cpp:74 qalculateeditfunctiondialog.cpp:583 +#: qalculateeditmatrixvectordialog.cpp:78 qalculateeditunitdialog.cpp:55 +#: qalculateeditunknownvariabledialog.cpp:47 +#: qalculateeditvariabledialog.cpp:49 qalculateimportcsvdialog.cpp:60 +msgid "Name:" +msgstr "Nom:" + +#: qalculateeditdatasetdialog.cpp:124 qalculateeditdatasetdialog.cpp:451 +#: qalculateeditfunctiondialog.cpp:83 qalculateeditmatrixvectordialog.cpp:87 +#: qalculateeditunitdialog.cpp:64 qalculateeditunknownvariabledialog.cpp:56 +#: qalculateeditvariabledialog.cpp:60 +msgid "Names Details" +msgstr "Détails des noms" + +#: qalculateeditdatasetdialog.cpp:126 +msgid "Object argument name:" +msgstr "Nom de l'argument de l'objet:" + +#: qalculateeditdatasetdialog.cpp:129 +msgid "Property argument name:" +msgstr "Nom de l'argument de la propriété" + +#: qalculateeditdatasetdialog.cpp:132 +msgid "Default property:" +msgstr "Propriété par défaut:" + +#: qalculateeditdatasetdialog.cpp:173 +msgid "text" +msgstr "texte" + +#: qalculateeditdatasetdialog.cpp:178 qalculateeditdatasetdialog.cpp:186 +msgid "approximate" +msgstr "approché" + +#: qalculateeditdatasetdialog.cpp:181 qalculateexpressionedit.cpp:712 +#: qalculatevariablesdialog.cpp:428 +msgid "number" +msgstr "nombre" + +#: qalculateeditdatasetdialog.cpp:189 +msgid "expression" +msgstr "expression" + +#: qalculateeditdatasetdialog.cpp:213 qalculateeditdatasetdialog.cpp:499 +#: qalculateeditfunctiondialog.cpp:190 qalculateeditmatrixvectordialog.cpp:185 +#: qalculateeditunitdialog.cpp:146 qalculateeditunknownvariabledialog.cpp:132 +#: qalculateeditvariabledialog.cpp:102 +msgid "Empty name field" +msgstr "Champ de nom vide" + +#: qalculateeditdatasetdialog.cpp:217 qalculateeditfunctiondialog.cpp:201 +msgid "" +"A function with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "Une fonction avec le même nom existe déjà. Voulez-vous l'écraser?" + +#: qalculateeditdatasetdialog.cpp:309 +msgid "Edit Data Set (global)" +msgstr "Éditer l'ensemble de données (global)" + +#: qalculateeditdatasetdialog.cpp:311 +msgid "New Data Set" +msgstr "Nouvel ensemble de données" + +#: qalculateeditdatasetdialog.cpp:322 +msgid "info" +msgstr "info" + +#: qalculateeditdatasetdialog.cpp:435 qalculateeditdatasetdialog.cpp:548 +msgid "Edit Property" +msgstr "Éditer la propriété" + +#: qalculateeditdatasetdialog.cpp:453 qalculateeditfunctiondialog.cpp:90 +#: qalculateeditmatrixvectordialog.cpp:93 qalculateeditunitdialog.cpp:66 +#: qalculateeditunknownvariabledialog.cpp:90 +#: qalculateeditvariabledialog.cpp:80 qalculateimportcsvdialog.cpp:63 +msgid "Descriptive name:" +msgstr "Nom descriptif:" + +#: qalculateeditdatasetdialog.cpp:464 +msgid "Value type:" +msgstr "Type de valeur:" + +#: qalculateeditdatasetdialog.cpp:467 qalculateeditfunctiondialog.cpp:593 +msgid "Text" +msgstr "Texte" + +#: qalculateeditdatasetdialog.cpp:469 qalculateeditfunctiondialog.cpp:482 +#: qalculateplotdialog.cpp:154 +msgid "Expression" +msgstr "Expression" + +#: qalculateeditdatasetdialog.cpp:474 +msgid "Use as key" +msgstr "Utiliser comme clé" + +#: qalculateeditdatasetdialog.cpp:476 +msgid "Approximate value" +msgstr "Valeur approchée" + +#: qalculateeditdatasetdialog.cpp:478 +msgid "Case sensitive value" +msgstr "Valeur sensible à la casse" + +#: qalculateeditdatasetdialog.cpp:480 +msgid "Value uses brackets" +msgstr "La valeur utilise des crochets" + +#: qalculateeditdatasetdialog.cpp:550 +msgid "New Property" +msgstr "Nouvelle propriété" + +#: qalculateeditdatasetdialog.cpp:615 qalculateeditnamesdialog.cpp:34 +msgid "Edit Names" +msgstr "Éditer les noms" + +#: qalculateeditdatasetdialog.cpp:621 qalculateeditfunctiondialog.cpp:481 +#: qalculateeditnamesdialog.cpp:46 +msgid "Reference" +msgstr "Référence" + +#: qalculateeditfunctiondialog.cpp:55 qalculateeditfunctiondialog.cpp:286 +msgid "Edit Function" +msgstr "Éditer la fonction" + +#: qalculateeditfunctiondialog.cpp:85 qalculateeditmatrixvectordialog.cpp:89 +#: qalculateeditunitdialog.cpp:87 qalculateeditunknownvariabledialog.cpp:85 +#: qalculateeditvariabledialog.cpp:74 qalculateimportcsvdialog.cpp:66 +msgid "Category:" +msgstr "Catégorie :" + +#: qalculateeditfunctiondialog.cpp:96 +msgid "Hide function" +msgstr "Cacher la fonction" + +#: qalculateeditfunctiondialog.cpp:106 qalculateplotdialog.cpp:89 +msgid "Expression:" +msgstr "Expression :" + +#: qalculateeditfunctiondialog.cpp:115 +msgid "Condition:" +msgstr "Condition :" + +#: qalculateeditfunctiondialog.cpp:120 qalculateeditfunctiondialog.cpp:476 +msgid "Sub-Functions" +msgstr "Sous-fonctions" + +#: qalculateeditfunctiondialog.cpp:122 +msgid "Arguments:" +msgstr "Arguments :" + +#: qalculateeditfunctiondialog.cpp:197 +msgid "Empty expression field" +msgstr "Champ d'expression vide" + +#: qalculateeditfunctiondialog.cpp:288 +msgid "Edit Function (global)" +msgstr "Éditer la fonction (global)" + +#: qalculateeditfunctiondialog.cpp:290 +msgid "New Function" +msgstr "Nouvelle fonction" + +#: qalculateeditfunctiondialog.cpp:483 +msgid "Precalculate" +msgstr "Précalculer" + +#: qalculateeditfunctiondialog.cpp:579 qalculateeditfunctiondialog.cpp:675 +msgid "Edit Argument" +msgstr "Éditer l'argument" + +#: qalculateeditfunctiondialog.cpp:586 +msgid "Type:" +msgstr "Type :" + +#: qalculateeditfunctiondialog.cpp:589 +msgid "Free" +msgstr "Libre" + +#: qalculateeditfunctiondialog.cpp:592 +msgid "Symbol" +msgstr "Symbole" + +#: qalculateeditfunctiondialog.cpp:594 qalculateinsertfunctiondialog.cpp:353 +msgid "Date" +msgstr "Date" + +#: qalculateeditfunctiondialog.cpp:597 +msgid "Boolean" +msgstr "Booléen" + +#: qalculateeditfunctiondialog.cpp:603 +msgid "Angle" +msgstr "Angle" + +#: qalculateeditfunctiondialog.cpp:605 +msgid "Enable rules and type test" +msgstr "Activer les règles et le test du type" + +#: qalculateeditfunctiondialog.cpp:607 +msgid "Custom condition:" +msgstr "Condition personnalisée" + +#: qalculateeditfunctiondialog.cpp:611 +msgid "Allow matrix" +msgstr "Autoriser les matrices" + +#: qalculateeditfunctiondialog.cpp:613 +msgid "Forbid zero" +msgstr "Interdire zéro" + +#: qalculateeditfunctiondialog.cpp:615 +msgid "Allow complex" +msgstr "Autoriser les nombres complexes" + +#: qalculateeditfunctiondialog.cpp:617 qalculateplotdialog.cpp:164 +msgid "Min:" +msgstr "Min :" + +#: qalculateeditfunctiondialog.cpp:624 qalculateeditfunctiondialog.cpp:633 +msgid "Include equals" +msgstr "Inclure les égalités" + +#: qalculateeditfunctiondialog.cpp:626 qalculateplotdialog.cpp:167 +msgid "Max:" +msgstr "Max :" + +#: qalculateeditfunctiondialog.cpp:677 +msgid "New Argument" +msgstr "Nouvel argument" + +#: qalculateeditmatrixvectordialog.cpp:71 +#: qalculateeditunknownvariabledialog.cpp:40 +#: qalculateeditvariabledialog.cpp:41 qalculateeditvariabledialog.cpp:180 +#: qalculateinsertmatrixvectordialog.cpp:71 +msgid "Edit Variable" +msgstr "Éditer la variable" + +#: qalculateeditmatrixvectordialog.cpp:96 +#: qalculateinsertmatrixvectordialog.cpp:75 +msgid "Rows:" +msgstr "Lignes :" + +#: qalculateeditmatrixvectordialog.cpp:99 +#: qalculateinsertmatrixvectordialog.cpp:78 +msgid "Columns:" +msgstr "Colonnes :" + +#: qalculateeditmatrixvectordialog.cpp:112 +#: qalculateeditmatrixvectordialog.cpp:133 +#: qalculateeditmatrixvectordialog.cpp:295 +#: qalculateinsertmatrixvectordialog.cpp:91 +#: qalculateinsertmatrixvectordialog.cpp:115 +#: qalculateinsertmatrixvectordialog.cpp:275 +msgid "Elements:" +msgstr "Éléments :" + +#: qalculateeditmatrixvectordialog.cpp:146 +#: qalculateeditmatrixvectordialog.cpp:292 +#: qalculateinsertmatrixvectordialog.cpp:128 +#: qalculateinsertmatrixvectordialog.cpp:272 +msgid "Elements (in horizontal order):" +msgstr "Éléments (par ordre horizontal) :" + +#: qalculateeditmatrixvectordialog.cpp:189 +#: qalculateeditunknownvariabledialog.cpp:136 +#: qalculateeditvariabledialog.cpp:114 +msgid "" +"An unit or variable with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" +"Une unité avec le même nom existe déjà.\n" +"Voulez-vous l'écraser?" + +#: qalculateeditmatrixvectordialog.cpp:301 +msgid "Edit Vector" +msgstr "Éditer le vecteur" + +#: qalculateeditmatrixvectordialog.cpp:303 +msgid "Edit Vector (global)" +msgstr "Éditer le vecteur (global)" + +#: qalculateeditmatrixvectordialog.cpp:305 +msgid "New Vector" +msgstr "Nouveau vecteur" + +#: qalculateeditmatrixvectordialog.cpp:310 +msgid "Edit Matrix" +msgstr "Éditer la matrice" + +#: qalculateeditmatrixvectordialog.cpp:312 +msgid "Edit Matrix (global)" +msgstr "Éditer la matrice (global)" + +#: qalculateeditmatrixvectordialog.cpp:314 +msgid "New Matrix" +msgstr "Nouvelle matrice" + +#: qalculateeditnamesdialog.cpp:42 +msgid "Abbreviation" +msgstr "Abréviation" + +#: qalculateeditnamesdialog.cpp:44 +msgid "Plural" +msgstr "Pluriel" + +#: qalculateeditnamesdialog.cpp:48 +msgid "Avoid Input" +msgstr "Éviter la saisie" + +#: qalculateeditnamesdialog.cpp:50 +msgid "Unicode" +msgstr "Unicode" + +#: qalculateeditnamesdialog.cpp:52 +msgid "Suffix" +msgstr "Suffixe" + +#: qalculateeditnamesdialog.cpp:54 +msgid "Case Sensitive" +msgstr "Sensible à la casse" + +#: qalculateeditunitdialog.cpp:43 qalculateeditunitdialog.cpp:287 +msgid "Edit Unit" +msgstr "Éditer l'unité" + +#: qalculateeditunitdialog.cpp:72 +msgid "Hide unit" +msgstr "Cacher l'unité" + +#: qalculateeditunitdialog.cpp:80 +msgid "Class:" +msgstr "Classe :" + +#: qalculateeditunitdialog.cpp:83 +msgid "Base Unit" +msgstr "Unité de base" + +#: qalculateeditunitdialog.cpp:84 +msgid "Alias" +msgstr "Alias" + +#: qalculateeditunitdialog.cpp:85 +msgid "Composite Unit" +msgstr "Unité composée" + +#: qalculateeditunitdialog.cpp:92 +msgid "System:" +msgstr "Système :" + +#: qalculateeditunitdialog.cpp:95 +msgid "SI" +msgstr "SI" + +#: qalculateeditunitdialog.cpp:96 +msgid "CGS" +msgstr "CGS" + +#: qalculateeditunitdialog.cpp:97 +msgid "Imperial" +msgstr "Impérial" + +#: qalculateeditunitdialog.cpp:98 +msgid "US Survey" +msgstr "Étude américaine" + +#: qalculateeditunitdialog.cpp:102 +msgid "Relation" +msgstr "Relation" + +#: qalculateeditunitdialog.cpp:107 +msgid "Base unit:" +msgstr "Unité de base :" + +#: qalculateeditunitdialog.cpp:110 +msgid "Exponent:" +msgstr "Exposant :" + +#: qalculateeditunitdialog.cpp:114 +msgid "Relation:" +msgstr "Relation :" + +#: qalculateeditunitdialog.cpp:121 +msgid "Relation is exact" +msgstr "La relation est exacte" + +#: qalculateeditunitdialog.cpp:123 +msgid "Inverse relation:" +msgstr "Relation inverse :" + +#: qalculateeditunitdialog.cpp:150 +msgid "" +"A variable or unit with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" +"Une variable avec le même nom existe déjà.\n" +"Voulez-vous l'écraser?" + +#: qalculateeditunitdialog.cpp:175 qalculateeditunitdialog.cpp:219 +msgid "Base unit does not exist" +msgstr "L'unité de base n'existe pas" + +#: qalculateeditunitdialog.cpp:289 +msgid "Edit Unit (global)" +msgstr "Éditer l'unité (global)" + +#: qalculateeditunitdialog.cpp:291 +msgid "New Unit" +msgstr "Nouvelle unité" + +#: qalculateeditunknownvariabledialog.cpp:58 +msgid "Custom assumptions:" +msgstr "Hypothèses personnalisées" + +#: qalculateeditunknownvariabledialog.cpp:68 +msgid "Complex Number" +msgstr "Nombre complexe" + +#: qalculateeditunknownvariabledialog.cpp:69 +msgid "Real Number" +msgstr "Nombre réel" + +#: qalculateeditunknownvariabledialog.cpp:70 +msgid "Rational Number" +msgstr "Nombre rationnel" + +#: qalculateeditunknownvariabledialog.cpp:73 +msgid "Sign" +msgstr "Signe" + +#: qalculateeditunknownvariabledialog.cpp:199 +msgid "Edit Unknown Variable" +msgstr "Éditer la variable inconnue" + +#: qalculateeditunknownvariabledialog.cpp:201 +msgid "Edit Unknown Variable (global)" +msgstr "Éditer la variable inconnue (global)" + +#: qalculateeditunknownvariabledialog.cpp:203 +msgid "New Unknown Variable" +msgstr "Nouvelle variable inconnue" + +#: qalculateeditvariabledialog.cpp:63 qalculateinsertfunctiondialog.cpp:91 +msgid "Value:" +msgstr "Valeur :" + +#: qalculateeditvariabledialog.cpp:71 +msgid "Value is exact" +msgstr "La valeur est exacte" + +#: qalculateeditvariabledialog.cpp:110 +msgid "Empty value field" +msgstr "Champ de valeur vide" + +#: qalculateeditvariabledialog.cpp:182 +msgid "Edit Variable (global)" +msgstr "Éditer la variable (global)" + +#: qalculateeditvariabledialog.cpp:185 +msgid "New Variable" +msgstr "Nouvelle variable" + +#: qalculateexportcsvdialog.cpp:37 qalculateexportcsvdialog.cpp:54 +msgid "Export CSV File" +msgstr "Exporter le fichier CSV" + +#: qalculateexportcsvdialog.cpp:42 +msgid "Current result" +msgstr "Résultat actuel" + +#: qalculateexportcsvdialog.cpp:46 +msgid "Matrix/vector variable" +msgstr "Variable matricielle/vectorielle" + +#: qalculateexportcsvdialog.cpp:51 qalculateimportcsvdialog.cpp:43 +msgid "File:" +msgstr "Fichier :" + +#: qalculateexportcsvdialog.cpp:56 qalculateimportcsvdialog.cpp:80 +msgid "Delimiter:" +msgstr "Délimiteur :" + +#: qalculateexportcsvdialog.cpp:59 qalculateimportcsvdialog.cpp:83 +msgid "Comma" +msgstr "Virgule" + +#: qalculateexportcsvdialog.cpp:60 qalculateimportcsvdialog.cpp:84 +msgid "Tabulator" +msgstr "Tabulation" + +#: qalculateexportcsvdialog.cpp:61 qalculateimportcsvdialog.cpp:85 +msgid "Semicolon" +msgstr "Point-virgule" + +#: qalculateexportcsvdialog.cpp:62 qalculateimportcsvdialog.cpp:86 +msgid "Space" +msgstr "Espace" + +#: qalculateexportcsvdialog.cpp:63 qalculateimportcsvdialog.cpp:87 +msgid "Other" +msgstr "Autre" + +#: qalculateexportcsvdialog.cpp:93 qalculateimportcsvdialog.cpp:116 +msgid "No file name entered." +msgstr "Vous n'avez pas entré de nom de fichier." + +#: qalculateexportcsvdialog.cpp:122 qalculateimportcsvdialog.cpp:145 +msgid "No delimiter selected." +msgstr "Vous n'avez pas entré de délimiteur." + +#: qalculateexportcsvdialog.cpp:135 +msgid "No variable name entered." +msgstr "Vous n'avez pas entré de nom de variable." + +#: qalculateexportcsvdialog.cpp:147 +msgid "No known variable with entered name found." +msgstr "Aucune variable correspondant au nom entré n'a été trouvée." + +#: qalculateexportcsvdialog.cpp:154 +#, c-format +msgid "" +"Could not export to file \n" +"%s" +msgstr "" +"Impossible d'exporter dans le fichier \n" +"%s" + +#: qalculateexpressionedit.cpp:146 +msgid "Disable Completion" +msgstr "Désactiver le complètement" + +#: qalculateexpressionedit.cpp:147 +msgid "Enable Completion" +msgstr "Activer le complètement" + +#. i18n: file ./qalculate_kdeui.rc line 154 +#: qalculateexpressionedit.cpp:161 qalculateresultdisplay.cpp:333 rc.cpp:48 +#, no-c-format +msgid "Meta Modes" +msgstr "Méta-modes" + +#: qalculateexpressionedit.cpp:655 qalculatevariablesdialog.cpp:366 +msgid "a previous result" +msgstr "un résultat précédent" + +#: qalculateexpressionedit.cpp:661 qalculatevariablesdialog.cpp:376 +msgid "matrix" +msgstr "matrice" + +#: qalculateexpressionedit.cpp:663 qalculatevariablesdialog.cpp:378 +msgid "vector" +msgstr "vecteur" + +#: qalculateexpressionedit.cpp:672 qalculatevariablesdialog.cpp:387 +msgid "positive" +msgstr "strictement positif" + +#: qalculateexpressionedit.cpp:676 qalculatevariablesdialog.cpp:391 +msgid "non-positive" +msgstr "négatif" + +#: qalculateexpressionedit.cpp:680 qalculatevariablesdialog.cpp:395 +msgid "negative" +msgstr "strictement négatif" + +#: qalculateexpressionedit.cpp:684 qalculatevariablesdialog.cpp:399 +msgid "non-negative" +msgstr "positif" + +#: qalculateexpressionedit.cpp:688 qalculatevariablesdialog.cpp:403 +msgid "non-zero" +msgstr "non nul" + +#: qalculateexpressionedit.cpp:696 qalculatevariablesdialog.cpp:412 +msgid "integer" +msgstr "entier" + +#: qalculateexpressionedit.cpp:700 qalculatevariablesdialog.cpp:416 +msgid "rational" +msgstr "rationnel" + +#: qalculateexpressionedit.cpp:704 qalculatevariablesdialog.cpp:420 +msgid "real" +msgstr "réel" + +#: qalculateexpressionedit.cpp:708 qalculatevariablesdialog.cpp:424 +msgid "complex" +msgstr "complexe" + +#: qalculateexpressionedit.cpp:716 qalculatevariablesdialog.cpp:432 +msgid "(not matrix)" +msgstr "(non matriciel)" + +#: qalculateexpressionedit.cpp:721 qalculatevariablesdialog.cpp:438 +msgid "unknown" +msgstr "inconnue" + +#: qalculateexpressionedit.cpp:723 qalculatevariablesdialog.cpp:440 +msgid "default assumptions" +msgstr "hypothèses par défaut" + +#: qalculatefunctionsdialog.cpp:47 +msgid "Functions" +msgstr "Fonctions" + +#: qalculatefunctionsdialog.cpp:59 +msgid "Function Name" +msgstr "Nom de fonction" + +#: qalculatefunctionsdialog.cpp:75 qalculatefunctionsdialog.cpp:313 +#: qalculateunitsdialog.cpp:99 qalculateunitsdialog.cpp:352 +#: qalculatevariablesdialog.cpp:74 qalculatevariablesdialog.cpp:349 +msgid "Deactivate" +msgstr "Désactiver" + +#: qalculatefunctionsdialog.cpp:174 qalculatefunctionsdialog.cpp:175 +#: qalculatefunctionsdialog.cpp:176 qalculatefunctionsdialog.cpp:234 +#: qalculatefunctionsdialog.cpp:260 qalculatefunctionsdialog.cpp:283 +#: qalculatefunctionsdialog.cpp:509 qalculateunitsdialog.cpp:206 +#: qalculateunitsdialog.cpp:207 qalculateunitsdialog.cpp:208 +#: qalculateunitsdialog.cpp:271 qalculateunitsdialog.cpp:297 +#: qalculateunitsdialog.cpp:320 qalculateunitsdialog.cpp:420 +#: qalculatevariablesdialog.cpp:174 qalculatevariablesdialog.cpp:175 +#: qalculatevariablesdialog.cpp:176 qalculatevariablesdialog.cpp:256 +#: qalculatevariablesdialog.cpp:282 qalculatevariablesdialog.cpp:320 +#: qalculatevariablesdialog.cpp:466 +msgid "Inactive" +msgstr "Désactivé" + +#: qalculatefunctionsdialog.cpp:315 qalculateunitsdialog.cpp:354 +#: qalculatevariablesdialog.cpp:351 +msgid "Activate" +msgstr "Activer" + +#: qalculatefunctionsdialog.cpp:367 qalculateresultdisplay.cpp:148 +#, c-format +msgid "" +"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." +msgstr "" +"Récupère des données de l'ensemble de données %s pour un objet et une " +"propriété données. Si \"info\" est entré comme propriété, une boîte de " +"dialogue s'ouvrira avec toutes les propriétés de l'objet." + +#: qalculatefunctionsdialog.cpp:391 +msgid "Arguments" +msgstr "Arguments" + +#: qalculatefunctionsdialog.cpp:412 qalculateinsertfunctiondialog.cpp:194 +#: qalculateinsertfunctiondialog.cpp:227 +msgid "optional" +msgstr "optionnel" + +#: qalculatefunctionsdialog.cpp:416 +msgid "default: " +msgstr "défaut :" + +#: qalculatefunctionsdialog.cpp:426 +msgid "Requirement" +msgstr "Exigence" + +#: qalculateimportcsvdialog.cpp:39 qalculateimportcsvdialog.cpp:46 +msgid "Import CSV File" +msgstr "Importer un fichier CSV" + +#: qalculateimportcsvdialog.cpp:48 +msgid "Import as:" +msgstr "Importer en tant que :" + +#: qalculateimportcsvdialog.cpp:71 +msgid "First row:" +msgstr "Première ligne :" + +#: qalculateimportcsvdialog.cpp:77 +#, fuzzy +msgid "Includes headings" +msgstr "Inclure les en-têtes" + +#: qalculateimportcsvdialog.cpp:149 +msgid "An error occured when importing the CSV file." +msgstr "Un erreur est survenue lors de l'importation du fichier CSV." + +#: qalculateinsertfunctiondialog.cpp:50 qalculateinsertfunctiondialog.cpp:57 +msgid "Execute" +msgstr "Exécuter" + +#: qalculateinsertfunctiondialog.cpp:93 +msgid "Argument" +msgstr "Argument" + +#: qalculateinsertfunctiondialog.cpp:152 +msgid "True" +msgstr "Vrai" + +#: qalculateinsertfunctiondialog.cpp:153 +msgid "False" +msgstr "Faux" + +#: qalculateinsertfunctiondialog.cpp:184 +msgid "Info" +msgstr "Info" + +#: qalculateinsertmatrixvectordialog.cpp:71 +msgid "Insert Selection" +msgstr "Insérer la sélection" + +#: qalculateinsertmatrixvectordialog.cpp:293 +msgid "Vector Result" +msgstr "Résultat vectoriel" + +#: qalculateinsertmatrixvectordialog.cpp:295 +msgid "Matrix Result" +msgstr "Résultat matriciel" + +#: qalculateperiodictabledialog.cpp:195 +msgid "Element Data" +msgstr "Donnée de l'élément" + +#: qalculateperiodictabledialog.cpp:221 +msgid "Classification" +msgstr "Classification" + +#: qalculateperiodictabledialog.cpp:224 +msgid "Alkali Metal" +msgstr "Métal alcalin" + +#: qalculateperiodictabledialog.cpp:225 +msgid "Alkaline-Earth Metal" +msgstr "Métal alcalino-terreux" + +#: qalculateperiodictabledialog.cpp:226 +msgid "Lanthanide" +msgstr "Lanthanide" + +#: qalculateperiodictabledialog.cpp:227 +msgid "Actinide" +msgstr "Actinide" + +#: qalculateperiodictabledialog.cpp:228 +msgid "Transition Metal" +msgstr "Métal de transition" + +#: qalculateperiodictabledialog.cpp:229 +msgid "Metal" +msgstr "Métal" + +#: qalculateperiodictabledialog.cpp:230 +msgid "Metalloid" +msgstr "Métalloïde" + +#: qalculateperiodictabledialog.cpp:231 +msgid "Non-Metal" +msgstr "Non métal" + +#: qalculateperiodictabledialog.cpp:232 +msgid "Halogen" +msgstr "Halogène" + +#: qalculateperiodictabledialog.cpp:233 +msgid "Noble Gas" +msgstr "Gaz noble" + +#: qalculateperiodictabledialog.cpp:234 +msgid "Transactinide" +msgstr "Transactinide" + +#: qalculateplotdialog.cpp:64 +msgid "Plot" +msgstr "Graphique" + +#: qalculateplotdialog.cpp:82 +msgid "Data" +msgstr "Donnée" + +#: qalculateplotdialog.cpp:83 +msgid "Function Range" +msgstr "Ensemble de départ" + +#: qalculateplotdialog.cpp:101 +msgid "Vector/matrix" +msgstr "Vecteur/Matrice" + +#: qalculateplotdialog.cpp:104 +msgid "Paired matrix" +msgstr "Matrice à deux colonnes" + +#: qalculateplotdialog.cpp:107 +msgid "Rows" +msgstr "Lignes" + +#: qalculateplotdialog.cpp:109 +msgid "X variable:" +msgstr "Varable X :" + +#: qalculateplotdialog.cpp:113 +msgid "Style:" +msgstr "Style :" + +#: qalculateplotdialog.cpp:115 +msgid "Line" +msgstr "Ligne" + +#: qalculateplotdialog.cpp:116 +msgid "Points" +msgstr "Points" + +#: qalculateplotdialog.cpp:117 +msgid "Line with points" +msgstr "Ligne avec des points" + +#: qalculateplotdialog.cpp:118 +msgid "Boxes/bars" +msgstr "Boîtes/barres" + +#: qalculateplotdialog.cpp:119 +msgid "Histogram" +msgstr "Histogramme" + +#: qalculateplotdialog.cpp:120 +msgid "Steps" +msgstr "Histogramme" + +#: qalculateplotdialog.cpp:121 +msgid "Candlesticks" +msgstr "" + +#: qalculateplotdialog.cpp:122 +msgid "Dots" +msgstr "Points" + +#: qalculateplotdialog.cpp:124 +msgid "Smoothing:" +msgstr "Lissage :" + +#: qalculateplotdialog.cpp:127 +msgid "Monotonic" +msgstr "Monotone" + +#: qalculateplotdialog.cpp:128 +msgid "Natural cubic splines" +msgstr "Splines cubiques naturelles" + +#: qalculateplotdialog.cpp:129 +msgid "Bezier" +msgstr "Bézier" + +#: qalculateplotdialog.cpp:130 +msgid "Bezier (monotonic)" +msgstr "Bézier (monotone)" + +#: qalculateplotdialog.cpp:132 +msgid "Y-axis:" +msgstr "Axe des Y :" + +#: qalculateplotdialog.cpp:136 +msgid "Primary" +msgstr "Primaire" + +#: qalculateplotdialog.cpp:139 +msgid "Secondary" +msgstr "Secondaire" + +#: qalculateplotdialog.cpp:171 +msgid "Sampling rate:" +msgstr "Taux d'échantillonage :" + +#: qalculateplotdialog.cpp:176 +msgid "Step size:" +msgstr "Taille des pas" + +#: qalculateplotdialog.cpp:194 +msgid "Display grid" +msgstr "Afficher la grille" + +#: qalculateplotdialog.cpp:196 +msgid "Display full border" +msgstr "Afficher toute la bordure" + +#: qalculateplotdialog.cpp:199 +msgid "Logarithmic x scale:" +msgstr "Échelle des X logarithmique :" + +#: qalculateplotdialog.cpp:203 +msgid "Logarithmic y scale:" +msgstr "Échelle des Y logarithmique :" + +#: qalculateplotdialog.cpp:207 +msgid "X-axis label:" +msgstr "Étiquette de l'axe des X :" + +#: qalculateplotdialog.cpp:210 +msgid "Y-axis label:" +msgstr "Étiquette de l'axe des Y :" + +#: qalculateplotdialog.cpp:213 +msgid "Color display:" +msgstr "Affichage de la couleur :" + +#: qalculateplotdialog.cpp:217 +msgid "Color" +msgstr "Couleur" + +#: qalculateplotdialog.cpp:220 +msgid "Monochrome" +msgstr "Monochrome" + +#: qalculateplotdialog.cpp:224 +msgid "Legend placement:" +msgstr "Placement de la légende :" + +#: qalculateplotdialog.cpp:227 +msgid "Top-left" +msgstr "En haut à gauche" + +#: qalculateplotdialog.cpp:228 +msgid "Top-right" +msgstr "En haut à droite" + +#: qalculateplotdialog.cpp:229 +msgid "Bottom-left" +msgstr "En bas à gauche" + +#: qalculateplotdialog.cpp:230 +msgid "Bottom-right" +msgstr "En bas à droite" + +#: qalculateplotdialog.cpp:231 +msgid "Below" +msgstr "En dessous" + +#: qalculateplotdialog.cpp:232 +msgid "Outside" +msgstr "En dehors" + +#: qalculateplotdialog.cpp:403 qalculateplotdialog.cpp:458 +#: qalculateplotdialog.cpp:506 +msgid "Empty expression." +msgstr "Expression vide." + +#: qalculateplotdialog.cpp:472 qalculateplotdialog.cpp:519 +msgid "Empty x variable." +msgstr "Variable x vide." + +#: qalculateprecisiondialog.cpp:34 qalculateprecisiondialog.cpp:36 +msgid "Recalculate" +msgstr "Recalculer" + +#: qalculateprecisiondialog.cpp:41 +msgid "Precision:" +msgstr "Précision :" + +#: qalculatepreferencesdialog.cpp:100 +msgid "Choose..." +msgstr "Choisir..." + +#: qalculatepreferencesdialog.cpp:147 +msgid "Preferences" +msgstr "Préférences" + +#: qalculatepreferencesdialog.cpp:161 +msgid "Close to system tray" +msgstr "Fermer vers la boîte à miniatures" + +#: qalculatepreferencesdialog.cpp:162 +msgid "" +"If the application will reside in the system tray when the window is closed" +msgstr "" +"Si l'application résidera dans la boîte à miniatures lorsque à la fermeture " +"de la fenêtre" + +#: qalculatepreferencesdialog.cpp:164 +msgid "Display expression status" +msgstr "Affiche le résultat de l'expression" + +#: qalculatepreferencesdialog.cpp:165 +msgid "" +"If as-you-type expression status shall be displayed below the expression " +"entry" +msgstr "" +"Si une expression s'affichant au fil de la frappe doit s'afficher sous " +"l'entrée de l'expression." + +#: qalculatepreferencesdialog.cpp:167 +msgid "Use icon buttons" +msgstr "Utiliser des boutons sous forme d'icône" + +#: qalculatepreferencesdialog.cpp:168 +msgid "" +"Use icons instead of text on the top-right buttons. The third state uses the " +"style setting for icons on buttons." +msgstr "" +"Utiliser des icônes plutôt que du texte dans les boutons en haut à droite. " +"Le troisième état utilise les préférences de style pour les icônes sur les " +"boutons." + +#: qalculatepreferencesdialog.cpp:171 +msgid "Update exchange rates on start" +msgstr "Mettre à jour les taux d'échange au démarrage" + +#: qalculatepreferencesdialog.cpp:172 +msgid "" +"If current exchange rates shall be downloaded from the internet at program " +"start" +msgstr "" +"Si les taux d'échange doivent être téléchargés sur internet au démarrage du " +"programme" + +#: qalculatepreferencesdialog.cpp:174 +msgid "Save mode on exit" +msgstr "Enregistrer le mode en quittant" + +#: qalculatepreferencesdialog.cpp:175 +msgid "If the mode of the calculator shall be restored" +msgstr "Si le mode de la calculatrice doit être restauré" + +#: qalculatepreferencesdialog.cpp:177 +msgid "Save definitions on exit" +msgstr "Enregistrer les définitions en quittant" + +#: qalculatepreferencesdialog.cpp:178 +msgid "" +"If changes to functions, units and variables shall be saved automatically" +msgstr "" +"Si les modifications apportées aux fonctions, unités et variables doivent " +"être automatiquement enregistrées" + +#: qalculatepreferencesdialog.cpp:180 +msgid "Use only keypad keys for RPN" +msgstr "N'utiliser que les touches du pavé numériquer pour la NPI" + +#: qalculatepreferencesdialog.cpp:181 +msgid "" +"Use only keypad keys for RPN operations (+-*/^) and use the rest of the " +"keyboard for expression entry" +msgstr "" +"N'utiliser que les touches du pavé numérique pour les opération NPI (+-*/^) " +"et utiliser le reste du clavier pour la saisie d'expressions" + +#: qalculatepreferencesdialog.cpp:183 +msgid "Ignores dots in numbers" +msgstr "Ignore les points dans les nombres" + +#: qalculatepreferencesdialog.cpp:184 +msgid "" +"Allow dots, '.', to be used as thousands separator instead of as an " +"alternative to decimal sign" +msgstr "" +"Permettre les points, '.', comme séparateur des milliers au lieu d'une " +"alternative au signe décimal." + +#: qalculatepreferencesdialog.cpp:187 +msgid "Enable unicode signs" +msgstr "Activer les signes unicode" + +#: qalculatepreferencesdialog.cpp:188 +msgid "Disable this if you have problems with some fancy characters" +msgstr "" +"Désactivez cette option si vous avez des problèmes avec certains caractères " +"spéciaux" + +#: qalculatepreferencesdialog.cpp:190 +msgid "Use lower case in numbers" +msgstr "Utiliser les minuscules dans les nombres" + +#: qalculatepreferencesdialog.cpp:191 +msgid "If lower case letters should be used in numbers with non-decimal base" +msgstr "" +"Si des lettres en minuscules doivent être utilisées dans les nombres avec " +"une base non décimale" + +#: qalculatepreferencesdialog.cpp:193 +msgid "Use lower case \"e\"" +msgstr "Utiliser la minuscule \"e\"" + +#: qalculatepreferencesdialog.cpp:194 +msgid "If \"e\"; shall be used instead of \"E\" in numbers" +msgstr "Si \"e\" doit être utilisé au lieu de \"E\" dans les nombres" + +#: qalculatepreferencesdialog.cpp:196 +msgid "Alternative base prefixes" +msgstr "Préfixes des bases alternatives" + +#: qalculatepreferencesdialog.cpp:197 +msgid "" +"If hexadecimal numbers shall be displayed with \"0x0\" and binary numbers " +"with \"0b00\" as prefixes" +msgstr "" +"Si les nombres hexadécimaux doivent être affichés avecle préfixe \"0x0\" et " +"les nombres binaires avec \"0b00\"" + +#: qalculatepreferencesdialog.cpp:199 +msgid "Spell out logical operators" +msgstr "Écrire les opérateurs logiques en toutes lettres" + +#: qalculatepreferencesdialog.cpp:200 +msgid "If logical and/or shall be displayed as \"&&\"/\"||\" or \"and\"/\"or\"" +msgstr "" +"Si les opérateurs logiques et/ou doivent être affichés \"&&\"/\"||\" ou \"et" +"\"/\"ou\"" + +#: qalculatepreferencesdialog.cpp:203 +msgid "Multiplication sign:" +msgstr "Signe de la multiplication :" + +#: qalculatepreferencesdialog.cpp:215 +msgid "Division sign:" +msgstr "Signe de la division :" + +#: qalculatepreferencesdialog.cpp:230 +msgid "Custom result font" +msgstr "Police du résultat personnalisée" + +#: qalculatepreferencesdialog.cpp:234 +msgid "Custom expression font" +msgstr "Police de l'expression personnalisée" + +#: qalculatepreferencesdialog.cpp:238 +msgid "Custom status font" +msgstr "Police de l'état personnalisée" + +#: qalculatepreferencesdialog.cpp:243 +msgid "Status error color:" +msgstr "Couleur des erreurs :" + +#: qalculatepreferencesdialog.cpp:250 +msgid "Status warning color:" +msgstr "Couleur des avertissements :" + +#: qalculateresultdisplay.cpp:52 +msgid "a matrix" +msgstr "une matrice" + +#: qalculateresultdisplay.cpp:54 +msgid "a vector" +msgstr "un vecteur" + +#: qalculateresultdisplay.cpp:57 +msgid "double-click to view/edit" +msgstr "double-cliquez pour voir/éditer" + +#: qalculateresultdisplay.cpp:60 +msgid "Unknown variable" +msgstr "Variable inconnue" + +#: qalculateresultdisplay.cpp:72 +msgid "Prefix" +msgstr "Préfixe" + +#: qalculateresultdisplay.cpp:336 +msgid "Show Parsed Expression" +msgstr "Afficher l'expression parcourue" + +#: qalculateresultdisplay.cpp:342 qalculateresultdisplay.cpp:353 +msgid "Show Object Info" +msgstr "Afficher l'information de l'objet" + +#: qalculateresultdisplay.cpp:348 +msgid "View/Edit Matrix" +msgstr "Voir/éditer la matrice" + +#: qalculateresultdisplay.cpp:350 +msgid "View/Edit Vector" +msgstr "Voir/éditer le vecteur" + +#: qalculateresultdisplay.cpp:382 +msgid "Parsed expression:" +msgstr "Expression parcourue :" + +#: qalculatesetbasedialog.cpp:33 +msgid "Result Base" +msgstr "Base du résultat" + +#: qalculatesetbasedialog.cpp:39 qalculatesetbasedialog.cpp:52 +msgid "Other:" +msgstr "Autre :" + +#: qalculatesetbasedialog.cpp:43 +msgid "Time format" +msgstr "Format de l'heure" + +#: qalculatesetbasedialog.cpp:44 qalculatesetbasedialog.cpp:55 +msgid "Roman numerals" +msgstr "Chiffres romains" + +#: qalculatesetbasedialog.cpp:46 +msgid "Expression Base" +msgstr "Base de l'expression" + +#: qalculateunitsdialog.cpp:54 +msgid "Units" +msgstr "Unités" + +#: qalculateunitsdialog.cpp:68 +msgid "Names" +msgstr "Noms" + +#: qalculateunitsdialog.cpp:69 +msgid "Base" +msgstr "Base" + +#: qalculateunitsdialog.cpp:72 +msgid "Conversion" +msgstr "Conversion" + +#: qalculateunitsdialog.cpp:105 +msgid "Convert Result" +msgstr "Convertir le résultat" + +#: qalculateunitsdialog.cpp:250 +msgid "Cannot delete unit as it is needed by other units." +msgstr "" +"Impossible de détruire l'unité car elle est utilisée par d'autres unités" + +#: qalculatevariablesdialog.cpp:51 +msgid "Variables" +msgstr "Variables" + +#: qalculatevariablesdialog.cpp:60 +msgid "Variable Name" +msgstr "Nom de variable" + +#. i18n: file ./qalculate_kdeui.rc line 5 +#: rc.cpp:6 +#, no-c-format +msgid "&New" +msgstr "&Nouveau" + +#. i18n: file ./qalculate_kdeui.rc line 37 +#: rc.cpp:12 +#, no-c-format +msgid "&Set Prefix" +msgstr "&Définir le préfixe" + +#. i18n: file ./qalculate_kdeui.rc line 39 +#: rc.cpp:15 +#, no-c-format +msgid "&Convert To Unit" +msgstr "&Convertir vers l'unité" + +#. i18n: file ./qalculate_kdeui.rc line 54 +#: rc.cpp:18 +#, no-c-format +msgid "&Mode" +msgstr "&Mode" + +#. i18n: file ./qalculate_kdeui.rc line 55 +#: rc.cpp:21 +#, no-c-format +msgid "Number Base" +msgstr "Base des nombres" + +#. i18n: file ./qalculate_kdeui.rc line 67 +#: rc.cpp:24 +#, no-c-format +msgid "Numerical Display" +msgstr "Affichage numérique" + +#. i18n: file ./qalculate_kdeui.rc line 80 +#: rc.cpp:27 +#, no-c-format +msgid "Fractional Display" +msgstr "Affichage sous forme de fraction" + +#. i18n: file ./qalculate_kdeui.rc line 86 +#: rc.cpp:30 +#, no-c-format +msgid "Unit Display" +msgstr "Affichage des unités" + +#. i18n: file ./qalculate_kdeui.rc line 96 +#: rc.cpp:33 +#, no-c-format +msgid "Angle Unit" +msgstr "Unité d'angle" + +#. i18n: file ./qalculate_kdeui.rc line 104 +#: rc.cpp:36 +#, no-c-format +msgid "Enabled Objects" +msgstr "Objets activés" + +#. i18n: file ./qalculate_kdeui.rc line 121 +#: rc.cpp:42 +#, no-c-format +msgid "Assumptions" +msgstr "Hypothèses" + +#. i18n: file ./qalculate_kdeui.rc line 137 +#: rc.cpp:45 +#, no-c-format +msgid "Algebraic Mode" +msgstr "Mode algébrique" + +#. i18n: file ./qalculate_kdeui.rc line 161 +#: rc.cpp:51 +#, no-c-format +msgid "Fu&nctions" +msgstr "Fo&nctions" + +#. i18n: file ./qalculate_kdeui.rc line 163 +#: rc.cpp:54 +#, no-c-format +msgid "&Variables" +msgstr "&Variables" + +#. i18n: file ./qalculate_kdeui.rc line 165 +#: rc.cpp:57 +#, no-c-format +msgid "&Units" +msgstr "&Unités" + +#~ msgid "10^x" +#~ msgstr "10^x" diff --git a/po/nl.po b/po/nl.po new file mode 100644 index 0000000..69d08c3 --- /dev/null +++ b/po/nl.po @@ -0,0 +1,2634 @@ +# translation of qalculate-kde.po to +# translation of qalculate_kde.po to +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# +# Rinse de Vries , 2006. +# Jaap Woldringh , 2006. +msgid "" +msgstr "" +"Project-Id-Version: qalculate_kde\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-05-08 14:44+0200\n" +"PO-Revision-Date: 07.11.YYYY 11:21\n" +"Last-Translator: Jaap Woldringh \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: _translatorinfo.cpp:1 +msgid "" +"_: NAME OF TRANSLATORS\n" +"Your names" +msgstr "Jaap Woldringh" + +#: _translatorinfo.cpp:3 +msgid "" +"_: EMAIL OF TRANSLATORS\n" +"Your emails" +msgstr "jjh punt woldringh op planet punt nl" + +#: kqalculate.cpp:264 +msgid "Remove from System Tray" +msgstr "Uit systeemvak verwijderen" + +#: kqalculate.cpp:265 qalculateeditdatasetdialog.cpp:471 +#: qalculateplotdialog.cpp:226 +msgid "Hide" +msgstr "Verbergen" + +#: kqalculate.cpp:286 kqalculate.cpp:4484 kqalculate.cpp:5915 +msgid "Enter" +msgstr "Invoeren" + +#: kqalculate.cpp:287 kqalculate.cpp:513 kqalculate.cpp:4485 +#: kqalculate.cpp:4492 kqalculate.cpp:5916 +msgid "=" +msgstr "=" + +#: kqalculate.cpp:289 kqalculate.cpp:514 kqalculate.cpp:4489 +#: kqalculate.cpp:4490 +msgid "Calculate expression and add to stack" +msgstr "" +"Expressie berekenen en plaats het antwoord in het stapelgeheugen (stack)" + +#: kqalculate.cpp:290 kqalculate.cpp:515 kqalculate.cpp:4493 +#: kqalculate.cpp:4494 +msgid "Calculate expression" +msgstr "Expressie berekenen" + +#: kqalculate.cpp:296 kqalculate.cpp:5918 +msgid "Store" +msgstr "Opslaan" + +#: kqalculate.cpp:298 +msgid "Store result as variable" +msgstr "Antwoord opslaan als een variabele" + +#: kqalculate.cpp:301 kqalculate.cpp:5920 qalculateconvertunitsdialog.cpp:42 +msgid "Convert" +msgstr "Converteren" + +#: kqalculate.cpp:303 +msgid "Convert units in result" +msgstr "Eenheden in het antwoord converteren" + +#: kqalculate.cpp:313 +msgid "Enter expression here" +msgstr "Expressie hier invoeren" + +#: kqalculate.cpp:322 +msgid "status" +msgstr "status" + +#: kqalculate.cpp:354 qalculateeditdataobjectdialog.cpp:71 +msgid "Exact" +msgstr "Exact" + +#: kqalculate.cpp:355 +msgid "Toggle exact mode" +msgstr "Exactmodus aan/uit" + +#: kqalculate.cpp:358 kqalculate.cpp:1070 +msgid "Fraction" +msgstr "Breuk" + +#: kqalculate.cpp:359 +msgid "Toggle fractional display" +msgstr "Tonen van breuken instellen" + +#: kqalculate.cpp:363 +msgid "Numerical display" +msgstr "Tonen van getallen" + +#: kqalculate.cpp:366 kqalculate.cpp:1046 qalculateresultdisplay.cpp:288 +msgid "Normal" +msgstr "Normaal" + +#: kqalculate.cpp:367 kqalculate.cpp:1048 qalculateresultdisplay.cpp:291 +msgid "Engineering" +msgstr "Technisch" + +#: kqalculate.cpp:368 kqalculate.cpp:1050 qalculateresultdisplay.cpp:294 +msgid "Scientific" +msgstr "Wetenschappelijk" + +#: kqalculate.cpp:369 +msgid "Pure" +msgstr "Zuiver" + +#: kqalculate.cpp:370 kqalculate.cpp:1054 +msgid "Simple" +msgstr "Eenvoudig" + +#: kqalculate.cpp:372 +msgid "Base in result" +msgstr "Grondtal in antwoord" + +#: kqalculate.cpp:376 kqalculate.cpp:1029 qalculatesetbasedialog.cpp:35 +#: qalculatesetbasedialog.cpp:48 +msgid "Binary" +msgstr "Binair" + +#: kqalculate.cpp:377 kqalculate.cpp:1031 qalculatesetbasedialog.cpp:36 +#: qalculatesetbasedialog.cpp:49 +msgid "Octal" +msgstr "Octaal" + +#: kqalculate.cpp:378 kqalculate.cpp:1033 kqalculate.cpp:1066 +#: qalculatesetbasedialog.cpp:37 qalculatesetbasedialog.cpp:50 +msgid "Decimal" +msgstr "Decimaal" + +#: kqalculate.cpp:379 kqalculate.cpp:1035 qalculatesetbasedialog.cpp:38 +#: qalculatesetbasedialog.cpp:51 +msgid "Hexadecimal" +msgstr "Hexadecimaal" + +#: kqalculate.cpp:380 kqalculate.cpp:1039 qalculatesetbasedialog.cpp:42 +msgid "Sexagesimal" +msgstr "Sexagesimaal" + +#: kqalculate.cpp:381 kqalculate.cpp:1041 +msgid "Time Format" +msgstr "Tijdnotatie" + +#: kqalculate.cpp:383 kqalculate.cpp:1037 +msgid "Other..." +msgstr "Overig..." + +#: kqalculate.cpp:389 +msgid "f(x)" +msgstr "f(x)" + +#: kqalculate.cpp:393 +msgid "Open functions manager" +msgstr "Functiebeheer openen" + +#: kqalculate.cpp:395 +msgid "sqrt" +msgstr "sqrt" + +#: kqalculate.cpp:396 +msgid "Square root" +msgstr "Vierkantswortel" + +#: kqalculate.cpp:399 kqalculate.cpp:947 +msgid "xy" +msgstr "xy" + +#: kqalculate.cpp:400 +msgid "Raise (Ctrl+*)" +msgstr "Machtsverheffen (Ctrl+*)" + +#: kqalculate.cpp:403 kqalculate.cpp:946 +msgid "x2" +msgstr "x2" + +#: kqalculate.cpp:404 +msgid "Square" +msgstr "Kwadraat" + +#: kqalculate.cpp:406 +msgid "log" +msgstr "log" + +#: kqalculate.cpp:407 +msgid "Base-10 logarithm" +msgstr "Logaritme met grondtal 10" + +#: kqalculate.cpp:409 +msgid "ln" +msgstr "ln" + +#: kqalculate.cpp:410 +msgid "Natural logarithm" +msgstr "Natuurlijke logaritme" + +#: kqalculate.cpp:412 +msgid "x!" +msgstr "x!" + +#: kqalculate.cpp:413 +msgid "Factorial" +msgstr "Faculteit" + +#: kqalculate.cpp:415 +msgid "cos" +msgstr "cos" + +#: kqalculate.cpp:416 +msgid "Cosine" +msgstr "Cosinus" + +#: kqalculate.cpp:418 +msgid "tan" +msgstr "tan" + +#: kqalculate.cpp:419 +msgid "Tangent" +msgstr "Tangens" + +#: kqalculate.cpp:421 +msgid "hyp" +msgstr "hyp" + +#: kqalculate.cpp:422 +msgid "Toggle hyperbolic functions" +msgstr "Hyperbolische functies aan/uit" + +#: kqalculate.cpp:425 +msgid "inv" +msgstr "inv" + +#: kqalculate.cpp:426 +msgid "Toggle inverse functions" +msgstr "Inverse functies aan/uit" + +#: kqalculate.cpp:429 +msgid "sin" +msgstr "sin" + +#: kqalculate.cpp:430 +msgid "Sine" +msgstr "Sinus" + +#: kqalculate.cpp:435 +msgid "Deg" +msgstr "Deg" + +#: kqalculate.cpp:436 +msgid "Angle Unit: Degrees" +msgstr "Hoekeenheid: Graden" + +#: kqalculate.cpp:439 +msgid "Rad" +msgstr "Rad" + +#: kqalculate.cpp:440 +msgid "Angle Unit: Radians" +msgstr "Hoekeenheid: Radialen" + +#: kqalculate.cpp:443 +msgid "Gra" +msgstr "Gra" + +#: kqalculate.cpp:444 +msgid "Angle Unit: Gradians" +msgstr "Hoekeenheid: Grads" + +#: kqalculate.cpp:447 kqalculate.cpp:1094 kqalculate.cpp:1152 +#: qalculateplotdialog.cpp:126 +msgid "None" +msgstr "Geen" + +#: kqalculate.cpp:464 +msgid "7" +msgstr "7" + +#: kqalculate.cpp:466 +msgid "8" +msgstr "8" + +#: kqalculate.cpp:468 +msgid "9" +msgstr "9" + +#: kqalculate.cpp:470 +msgid "4" +msgstr "4" + +#: kqalculate.cpp:472 +msgid "5" +msgstr "5" + +#: kqalculate.cpp:474 +msgid "6" +msgstr "6" + +#: kqalculate.cpp:476 +msgid "1" +msgstr "1" + +#: kqalculate.cpp:478 +msgid "2" +msgstr "2" + +#: kqalculate.cpp:480 +msgid "3" +msgstr "3" + +#: kqalculate.cpp:482 +msgid "0" +msgstr "0" + +#: kqalculate.cpp:485 +msgid "Decimal point" +msgstr "Decimale komma" + +#: kqalculate.cpp:487 +msgid "EXP" +msgstr "EXP" + +#: kqalculate.cpp:488 +msgid "10^x (Ctrl+Shift+E)" +msgstr "10^x (Ctrl+Shift+E)" + +#: kqalculate.cpp:491 +msgid "Del" +msgstr "Del" + +#: kqalculate.cpp:494 +msgid "AC" +msgstr "AC" + +#: kqalculate.cpp:498 +msgid "Multiply" +msgstr "Vermenigvuldigen" + +#: kqalculate.cpp:501 +msgid "Divide" +msgstr "Delen" + +#: kqalculate.cpp:507 +msgid "Subtract" +msgstr "Aftrekken" + +#: kqalculate.cpp:509 +msgid "Ans" +msgstr "Antw" + +#: kqalculate.cpp:510 +msgid "Previous result" +msgstr "Vorig antwoord" + +#: kqalculate.cpp:512 kqalculate.cpp:4488 +msgid "Ent" +msgstr "Ent" + +#: kqalculate.cpp:535 +msgid "Index" +msgstr "Index" + +#: kqalculate.cpp:536 qalculateeditdataobjectdialog.cpp:49 +#: qalculatevariablesdialog.cpp:61 +msgid "Value" +msgstr "Waarde" + +#: kqalculate.cpp:555 kqalculate.cpp:5924 +msgid "Up" +msgstr "Op" + +#: kqalculate.cpp:556 +msgid "Move selected register up" +msgstr "Geselecteerd register naar boven verplaatsen" + +#: kqalculate.cpp:560 kqalculate.cpp:5926 +msgid "Down" +msgstr "Neer" + +#: kqalculate.cpp:561 +msgid "Move selected register down" +msgstr "Geselecteerd register naar beneden verplaatsen" + +#: kqalculate.cpp:566 +msgid "Edit value of selected register" +msgstr "Waarde in geselecteerd register bewerken" + +#: kqalculate.cpp:571 +msgid "Delete selected register" +msgstr "Geselecteerd register wissen" + +#: kqalculate.cpp:576 +msgid "Clear the RPN stack" +msgstr "RPN-stapelgeheugen wissen" + +#: kqalculate.cpp:592 +msgid "Keypad" +msgstr "Toetsenbord" + +#: kqalculate.cpp:593 +msgid "Show/hide keypad" +msgstr "Toetsenbord tonen aan/uit" + +#: kqalculate.cpp:596 +msgid "History" +msgstr "Geschiedenis" + +#: kqalculate.cpp:597 +msgid "Show/hide history" +msgstr "Geschiedenis tonen aan/uit" + +#: kqalculate.cpp:600 +msgid "RPN Stack" +msgstr "RPN-stapelgeheugen (stack)" + +#: kqalculate.cpp:601 +msgid "Show/hide RPN stack" +msgstr "RPN-stapelgeheugen tonen aan/uit" + +#: kqalculate.cpp:716 kqalculate.cpp:2527 +msgid "RPN Register Moved" +msgstr "RPN-register is verplaatst" + +#: kqalculate.cpp:752 kqalculate.cpp:784 kqalculate.cpp:2138 +#: kqalculate.cpp:2702 kqalculate.cpp:2739 +msgid "approx." +msgstr "benadering" + +#: kqalculate.cpp:894 kqalculate.cpp:4813 +msgid "Load meta mode: %1" +msgstr "Inlezen metamodus: %1" + +#: kqalculate.cpp:966 +msgid "Qalculate! - Scientific Calculator" +msgstr "Qalculate! - Wetenschappelijke Rekenmachine" + +#: kqalculate.cpp:985 qalculateeditfunctiondialog.cpp:601 +#: qalculateresultdisplay.cpp:62 +msgid "Variable" +msgstr "Variabele" + +#: kqalculate.cpp:986 qalculateeditfunctiondialog.cpp:596 +#: qalculateeditmatrixvectordialog.cpp:106 qalculateimportcsvdialog.cpp:52 +#: qalculateinsertmatrixvectordialog.cpp:85 +#: qalculateinsertmatrixvectordialog.cpp:310 +msgid "Matrix" +msgstr "Matrix" + +#: kqalculate.cpp:987 qalculateeditfunctiondialog.cpp:595 +#: qalculateeditmatrixvectordialog.cpp:109 +#: qalculateinsertmatrixvectordialog.cpp:88 +#: qalculateinsertmatrixvectordialog.cpp:308 +msgid "Vector" +msgstr "Vector" + +#: kqalculate.cpp:988 +msgid "Unknown Variable" +msgstr "Onbekende variabele" + +#: kqalculate.cpp:989 qalculateeditdatasetdialog.cpp:70 +#: qalculateeditfunctiondialog.cpp:71 qalculateeditfunctiondialog.cpp:599 +#: qalculateplotdialog.cpp:98 qalculateresultdisplay.cpp:92 +msgid "Function" +msgstr "Functie" + +#: kqalculate.cpp:990 qalculatedatasetsdialog.cpp:64 +msgid "Data Set" +msgstr "Gegevensverzameling" + +#: kqalculate.cpp:991 qalculateconvertunitsdialog.cpp:68 +#: qalculateeditfunctiondialog.cpp:600 qalculateresultdisplay.cpp:67 +#: qalculateunitsdialog.cpp:67 +msgid "Unit" +msgstr "Eenheid" + +#: kqalculate.cpp:992 +msgid "Import CSV File..." +msgstr "CSV-bestand importeren..." + +#: kqalculate.cpp:993 +msgid "Export CSV File..." +msgstr "CSV-bestand exporteren..." + +#: kqalculate.cpp:994 +msgid "Store Result..." +msgstr "Antwoord opslaan..." + +#: kqalculate.cpp:995 +msgid "Save Result Image..." +msgstr "Afbeelding van het antwoord opslaan..." + +#: kqalculate.cpp:996 +msgid "Save Definitions" +msgstr "Definities bewaren" + +#: kqalculate.cpp:997 +msgid "Update Exchange Rates" +msgstr "Wisselkoersen bijwerken" + +#: kqalculate.cpp:998 +msgid "Plot Functions/Data" +msgstr "Functies/Gegevens plotten" + +#: kqalculate.cpp:1000 +msgid "Convert Number Bases" +msgstr "Getallen converteren naar ander grondtal" + +#: kqalculate.cpp:1001 qalculateperiodictabledialog.cpp:40 +msgid "Periodic Table" +msgstr "Periodiek systeem" + +#: kqalculate.cpp:1008 +msgid "Show/hide main Qalculate! window" +msgstr "Tonen/verbergen hoofdvenster van Qalculate!" + +#: kqalculate.cpp:1011 +msgid "Configure &Global Shortcuts..." +msgstr "&Globale sneltoetsen instellen..." + +#: kqalculate.cpp:1013 +msgid "Manage Variables" +msgstr "Variabelen beheren" + +#: kqalculate.cpp:1014 +msgid "Manage Functions" +msgstr "Functies beheren" + +#: kqalculate.cpp:1015 +msgid "Manage Units" +msgstr "Eenheden beheren" + +#: kqalculate.cpp:1016 +msgid "Manage Data Sets" +msgstr "Gegevensverzamelingen beheren" + +#: kqalculate.cpp:1017 kqalculate.cpp:1150 +msgid "Factorize" +msgstr "Ontbinden in factoren" + +#: kqalculate.cpp:1018 kqalculate.cpp:1148 +msgid "Simplify" +msgstr "Vereenvoudigen" + +#: kqalculate.cpp:1019 +msgid "Set Unknowns..." +msgstr "Onbekenden een waarde geven..." + +#: kqalculate.cpp:1020 +msgid "Convert to Unit Expression..." +msgstr "Converteren naar eenheidexpressie..." + +#: kqalculate.cpp:1021 kqalculate.cpp:1084 +msgid "Convert to Base Units" +msgstr "Converteren naar basiseenheden" + +#: kqalculate.cpp:1022 kqalculate.cpp:1086 +msgid "Convert to Best Unit" +msgstr "Converteren naar meest geschikte eenheid" + +#: kqalculate.cpp:1023 +msgid "Insert Matrix..." +msgstr "Matrix invoegen..." + +#: kqalculate.cpp:1024 +msgid "Insert Vector..." +msgstr "Vector invoegen..." + +#: kqalculate.cpp:1025 +msgid "Copy Result" +msgstr "Antwoord kopiëren" + +#: kqalculate.cpp:1026 +msgid "Clear History" +msgstr "Geschiedenis wissen" + +#: kqalculate.cpp:1027 +msgid "Configure Qalculate!" +msgstr "Qalculate! instellen" + +#: kqalculate.cpp:1043 +msgid "Roman Numerals" +msgstr "Romeinse cijfers" + +#: kqalculate.cpp:1045 +msgid "Select Result and Expression Base..." +msgstr "Grondtal voor antwoord en expressie selecteren..." + +#: kqalculate.cpp:1052 +msgid "Purely Scientific" +msgstr "Zuiver wetenschappelijk" + +#: kqalculate.cpp:1056 +msgid "Indicate Infinite Series" +msgstr "Oneindige reeks aangeven" + +#: kqalculate.cpp:1058 +msgid "Sort Minus Last" +msgstr "Sorteer minus het laatst" + +#: kqalculate.cpp:1060 +msgid "Negative Exponents" +msgstr "Negatieve exponenten" + +#: kqalculate.cpp:1062 +msgid "Show Ending Zeroes" +msgstr "Afsluitende nullen weergeven" + +#: kqalculate.cpp:1064 +msgid "Round Halfway Numbers to Even" +msgstr "Tussenliggende getallen naar even afronden" + +#: kqalculate.cpp:1068 +msgid "Decimal (Try Exact)" +msgstr "Decimaal (Exact proberen)" + +#: kqalculate.cpp:1072 +msgid "Combined" +msgstr "Gecombineerd" + +#: kqalculate.cpp:1074 +msgid "Enable Prefixes" +msgstr "Voorvoegsels toestaan" + +#: kqalculate.cpp:1076 +msgid "Enable Use of All SI Prefixes" +msgstr "Gebruik van alle SI-voorvoegsels toestaan" + +#: kqalculate.cpp:1078 +msgid "Enable Denominator Prefixes" +msgstr "Voorvoegsel voor noemer toestaan" + +#: kqalculate.cpp:1080 +msgid "Place Units Separately" +msgstr "Eenheden afzonderlijk plaatsen" + +#: kqalculate.cpp:1082 +msgid "No Automatic Conversion" +msgstr "Geen automatische conversie" + +#: kqalculate.cpp:1088 +msgid "Degrees" +msgstr "Graden (90 graden in rechte hoek)" + +#: kqalculate.cpp:1090 +msgid "Radians" +msgstr "Radialen" + +#: kqalculate.cpp:1092 +msgid "Gradians" +msgstr "Grads (100 grads in rechte hoek)" + +#: kqalculate.cpp:1096 +msgid "Abbreviate Names" +msgstr "Namen afkorten" + +#: kqalculate.cpp:1098 +msgid "Enable Variables" +msgstr "Variabelen toestaan" + +#: kqalculate.cpp:1100 +msgid "Enable Functions" +msgstr "Functies toestaan" + +#: kqalculate.cpp:1102 +msgid "Enable Units" +msgstr "Eenheden toestaan" + +#: kqalculate.cpp:1104 +msgid "Enable Unknowns" +msgstr "Onbekende variabelen toestaan" + +#: kqalculate.cpp:1106 +msgid "Calculate Variables" +msgstr "Variabelen berekenen" + +#: kqalculate.cpp:1108 +msgid "Allow Complex Result" +msgstr "Complexe antwoorden toestaan" + +#: kqalculate.cpp:1110 +msgid "Allow Infinite Result" +msgstr "Oneindige antwoorden toestaan" + +#: kqalculate.cpp:1112 +msgid "Try Exact" +msgstr "Exact proberen" + +#: kqalculate.cpp:1114 +msgid "Always Exact" +msgstr "Altijd exact" + +#: kqalculate.cpp:1116 qalculateeditdataobjectdialog.cpp:70 +msgid "Approximate" +msgstr "Benaderd" + +#: kqalculate.cpp:1118 kqalculate.cpp:1132 +#: qalculateeditunknownvariabledialog.cpp:65 +#: qalculateeditunknownvariabledialog.cpp:78 +#: qalculateperiodictabledialog.cpp:235 +msgid "Unknown" +msgstr "Onbekende" + +#: kqalculate.cpp:1120 qalculateeditunknownvariabledialog.cpp:66 +msgid "Not Matrix" +msgstr "Geen matrix" + +#: kqalculate.cpp:1122 qalculateeditdatasetdialog.cpp:468 +#: qalculateeditfunctiondialog.cpp:590 +#: qalculateeditunknownvariabledialog.cpp:67 +msgid "Number" +msgstr "Getal" + +#: kqalculate.cpp:1124 +msgid "Complex" +msgstr "Complex" + +#: kqalculate.cpp:1126 +msgid "Real" +msgstr "Reëel" + +#: kqalculate.cpp:1128 +msgid "Rational" +msgstr "Rationaal" + +#: kqalculate.cpp:1130 qalculateeditfunctiondialog.cpp:591 +#: qalculateeditunknownvariabledialog.cpp:71 +msgid "Integer" +msgstr "Geheel" + +#: kqalculate.cpp:1134 qalculateeditunknownvariabledialog.cpp:83 +msgid "Non-Zero" +msgstr "Ongelijk aan nul" + +#: kqalculate.cpp:1136 qalculateeditunknownvariabledialog.cpp:79 +msgid "Positive" +msgstr "Positief" + +#: kqalculate.cpp:1138 qalculateeditunknownvariabledialog.cpp:80 +msgid "Non-Negative" +msgstr "Niet-negatief" + +#: kqalculate.cpp:1140 qalculateeditunknownvariabledialog.cpp:81 +msgid "Negative" +msgstr "Negatief" + +#: kqalculate.cpp:1142 qalculateeditunknownvariabledialog.cpp:82 +msgid "Non-Positive" +msgstr "Niet-positief" + +#: kqalculate.cpp:1144 +msgid "Non-Zero Denominators" +msgstr "Noemers ongelijk aan nul" + +#: kqalculate.cpp:1146 +msgid "Warn About Denominators Assumed Non-Zero" +msgstr "Waarschuwen als noemers ongelijk nul worden aangenomen" + +#: kqalculate.cpp:1154 +msgid "Read Precision" +msgstr "Nauwkeurigheid lezen" + +#: kqalculate.cpp:1156 +msgid "Limit Implicit Multiplication" +msgstr "Impliciet vermenigvuldigen beperken" + +#: kqalculate.cpp:1158 +msgid "RPN Mode" +msgstr "RPN-modus" + +#: kqalculate.cpp:1160 +msgid "RPN Syntax" +msgstr "RPN-notatie" + +#: kqalculate.cpp:1162 qalculateprecisiondialog.cpp:31 +msgid "Precision" +msgstr "Nauwkeurigheid" + +#: kqalculate.cpp:1163 qalculatedecimalsdialog.cpp:27 +msgid "Decimals" +msgstr "Decimalen" + +#: kqalculate.cpp:1164 +msgid "Save Mode..." +msgstr "Modus opslaan..." + +#: kqalculate.cpp:1165 +msgid "Delete Mode..." +msgstr "Modus wissen..." + +#: kqalculate.cpp:1167 +msgid "Save Default Mode" +msgstr "Standaardmodus opslaan" + +#: kqalculate.cpp:1168 +msgid "Clear Stack" +msgstr "Stapelgeheugen wissen" + +#: kqalculate.cpp:1172 +msgid "Exp RPN Operation" +msgstr "Exp RPN-bewerking" + +#: kqalculate.cpp:1860 +msgid "and" +msgstr "and" + +#: kqalculate.cpp:1865 +msgid "or" +msgstr "or" + +#: kqalculate.cpp:2122 +msgid "undefined" +msgstr "ongedefinieerd" + +#: kqalculate.cpp:2164 +msgid "EXACT" +msgstr "EXACT" + +#: kqalculate.cpp:2167 +msgid "APPROX" +msgstr "BENADERING" + +#: kqalculate.cpp:2171 +msgid "RPN" +msgstr "RPN" + +#: kqalculate.cpp:2179 +msgid "BIN" +msgstr "BIN" + +#: kqalculate.cpp:2184 +msgid "OCT" +msgstr "OCT" + +#: kqalculate.cpp:2189 +msgid "HEX" +msgstr "HEX" + +#: kqalculate.cpp:2194 +msgid "ROMAN" +msgstr "ROMEINS" + +#: kqalculate.cpp:2206 +msgid "DEG" +msgstr "DEG" + +#: kqalculate.cpp:2211 +msgid "RAD" +msgstr "RAD" + +#: kqalculate.cpp:2216 +msgid "GRA" +msgstr "GRA" + +#: kqalculate.cpp:2223 +msgid "PREC" +msgstr "PREC" + +#: kqalculate.cpp:2228 +msgid "FUNC" +msgstr "FUNC" + +#: kqalculate.cpp:2234 +msgid "UNIT" +msgstr "EENH" + +#: kqalculate.cpp:2240 +msgid "VAR" +msgstr "VAR" + +#: kqalculate.cpp:2246 +msgid "INF" +msgstr "INF" + +#: kqalculate.cpp:2252 +msgid "CPLX" +msgstr "CPLX" + +#: kqalculate.cpp:2333 kqalculate.cpp:2351 kqalculate.cpp:2581 +msgid "aborted" +msgstr "afgebroken" + +#: kqalculate.cpp:2352 +msgid "calculation was aborted" +msgstr "berekening werd afgebroken" + +#: kqalculate.cpp:2588 +msgid "result processing was aborted" +msgstr "berekening werd afgebroken" + +#: kqalculate.cpp:2636 +msgid "Processing..." +msgstr "Verwerken..." + +#: kqalculate.cpp:2640 kqalculate.cpp:2885 kqalculate.cpp:3145 +msgid "Abort" +msgstr "Afbreken" + +#: kqalculate.cpp:2873 +msgid "Factorizing..." +msgstr "Ontbinden in factoren..." + +#: kqalculate.cpp:2877 +msgid "Simplifying..." +msgstr "Vereenvoudigen..." + +#: kqalculate.cpp:3141 +msgid "Calculating..." +msgstr "Berekenen..." + +#: kqalculate.cpp:3191 +msgid "RPN Operation" +msgstr "RPN-bewerking" + +#: kqalculate.cpp:3259 +msgid "Errors" +msgstr "Fouten" + +#: kqalculate.cpp:3260 +msgid "Warnings" +msgstr "Waarschuwingen" + +#: kqalculate.cpp:3270 +msgid "Couldn't write definitions" +msgstr "Kon definities niet schrijven" + +#: kqalculate.cpp:3538 +msgid "Prefixes" +msgstr "Voorvoegsels" + +#: kqalculate.cpp:3665 +msgid "No Prefix" +msgstr "Geen voorvoegsel" + +#: kqalculate.cpp:3816 qalculatevariablesdialog.cpp:191 +#: qalculatevariablesdialog.cpp:337 +msgid "Variable does not exist anymore." +msgstr "Variabele bestaat niet meer." + +#: kqalculate.cpp:3832 qalculateconvertunitsdialog.cpp:153 +#: qalculateunitsdialog.cpp:223 qalculateunitsdialog.cpp:337 +msgid "Unit does not exist anymore." +msgstr "Eenheid bestaat niet meer." + +#: kqalculate.cpp:3905 +msgid "Failed to download exchange rates from ECB." +msgstr "Het ophalen van de wisselkoersen van de ECB is mislukt." + +#: kqalculate.cpp:4752 +msgid "Save Mode" +msgstr "Modus opslaan" + +#: kqalculate.cpp:4755 +msgid "Mode name:" +msgstr "Modusnaam:" + +#: kqalculate.cpp:4765 +msgid "Shortcut:" +msgstr "Sneltoets:" + +#: kqalculate.cpp:4792 +msgid "Empty mode name." +msgstr "Geen modusnaam." + +#: kqalculate.cpp:4795 +msgid "Preset mode cannot be overwritten." +msgstr "Vooringestelde modus kan niet worden overschreven." + +#: kqalculate.cpp:4827 +msgid "Delete Mode" +msgstr "Modus wissen" + +#: kqalculate.cpp:4827 +msgid "Mode:" +msgstr "Modus:" + +#: kqalculate.cpp:5001 +msgid "log10 function not found." +msgstr "Kon log10-functie niet vinden." + +#: kqalculate.cpp:5545 main.cpp:156 main.cpp:159 main.cpp:160 main.cpp:161 +#: main.cpp:162 +msgid "Temporary" +msgstr "Tijdelijk" + +#: kqalculate.cpp:5567 kqalculate.cpp:5594 qalculatefunctionsdialog.cpp:191 +#: qalculatefunctionsdialog.cpp:300 +msgid "Function does not exist anymore." +msgstr "Functie bestaat niet meer." + +#: kqalculate.cpp:5697 kqalculate.cpp:5733 +msgid "My Variables" +msgstr "Mijn variabelen" + +#: kqalculate.cpp:5709 qalculateimportcsvdialog.cpp:56 +msgid "Vectors" +msgstr "Vectoren" + +#: kqalculate.cpp:5721 +msgid "Matrices" +msgstr "Matrices" + +#: kqalculate.cpp:5762 qalculateplotdialog.cpp:726 +msgid "Save Image" +msgstr "Afbeelding opslaan" + +#: kqalculate.cpp:5767 qalculateplotdialog.cpp:731 +msgid "" +"A file named \"%1\" already exists. Are you sure you want to overwrite it?" +msgstr "Een bestand met de naam \"%1\" bestaat al. Wilt u het overschrijven?" + +#: kqalculate.cpp:5767 qalculateplotdialog.cpp:731 +msgid "Overwrite File?" +msgstr "Bestand overschrijven?" + +#: kqalculate.cpp:5767 qalculateplotdialog.cpp:731 +msgid "&Overwrite" +msgstr "&Overschrijven" + +#: kqalculate.cpp:5801 +msgid "Failed to save image." +msgstr "Afbeelding opslaan is mislukt." + +#: kqalculate.cpp:6027 +msgid "No unknowns in result." +msgstr "Geen onbekenden in antwoord." + +#: kqalculate.cpp:6030 +msgid "Set Unknowns" +msgstr "Onbekenden een waarde geven" + +#: kqalculate.cpp:6194 +msgid "Too many arguments for %1()." +msgstr "Teveel argumenten voor %1()." + +#: kqalculate.cpp:6220 qalculatedatasetsdialog.cpp:342 +#: qalculatefunctionsdialog.cpp:343 qalculateresultdisplay.cpp:120 +msgid "argument" +msgstr "argument" + +#: kqalculate.cpp:6442 kqalculate.cpp:6446 +msgid "Edit Expression" +msgstr "Expressie bewerken" + +#: kqalculate.cpp:6451 +msgid "Edit Result" +msgstr "Antwoord bewerken" + +#: kqalculate.cpp:6454 +msgid "Insert Result Variable" +msgstr "Antwoordvariabele invoegen" + +#: main.cpp:45 +msgid "A powerful and easy to use desktop calculator" +msgstr "" +"Een gemakkelijk te gebruiken rekenmachine op het bureaublad met veel " +"mogelijkheden" + +#: main.cpp:51 +msgid "Calculate X11-clipboard content (selected text)" +msgstr "X11-klembordinhoud berekenen (geselecteerde tekst)" + +#: main.cpp:52 +msgid "Initial expression to calculate" +msgstr "Te berekenen initiële expressie" + +#: main.cpp:134 +msgid "Enter a mathematical expression above.
Ex. 5 + 2 / 3" +msgstr "Een rekenkundige expressie hierboven invoeren.
Bv.. 5 + 2 / 3" + +#: main.cpp:143 +msgid "" +"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" +"\n" +"Do you want to fetch exchange rates now from the Internet?" +msgstr "" +"U moet de wisselkoersen ophalen om van de ene naar de andere munteenheid te " +"kunnen converteren. U kunt de huidige wisselkoersen ophalen door " +"\"Wisselkoersen ophalen\" te selecteren in het menu Bestand.\n" +"\n" +"Wilt u de wisselkoersen nu ophalen van het internet?" + +#: main.cpp:143 +msgid "Update exchange rates?" +msgstr "Wisselkoersen bijwerken?" + +#: main.cpp:155 +msgid "ans" +msgstr "antw" + +#: main.cpp:156 +msgid "Last Answer" +msgstr "Laatste antwoord" + +#: main.cpp:157 +msgid "answer" +msgstr "antwoord" + +#: main.cpp:159 +msgid "Answer 2" +msgstr "Antwoord 2" + +#: main.cpp:160 +msgid "Answer 3" +msgstr "Antwoord 3" + +#: main.cpp:161 +msgid "Answer 4" +msgstr "Antwoord 4" + +#: main.cpp:162 +msgid "Answer 5" +msgstr "Antwoord 5" + +#: main.cpp:166 +msgid "Failed to load global definitions!" +msgstr "Het inlezen van de globale definities is mislukt!" + +#: main.cpp:290 +msgid "Qalculate!" +msgstr "Qalculate!" + +#: preferences.cpp:208 +msgid "Preset" +msgstr "Voorinstelling" + +#: preferences.cpp:669 +#, c-format +msgid "" +"Couldn't write preferences to\n" +"%s" +msgstr "" +"Kon de voorkeurinstellingen niet schrijven naar\n" +"%s" + +#: qalculateconvertnumberbasesdialog.cpp:31 qalculatesetbasedialog.cpp:29 +msgid "Number Bases" +msgstr "Grondtallen voor talstelsels" + +#: qalculateconvertnumberbasesdialog.cpp:37 +msgid "Decimal:" +msgstr "Decimaal:" + +#: qalculateconvertnumberbasesdialog.cpp:41 +msgid "Binary:" +msgstr "Binair:" + +#: qalculateconvertnumberbasesdialog.cpp:45 +msgid "Octal:" +msgstr "Octaal:" + +#: qalculateconvertnumberbasesdialog.cpp:49 +msgid "Hexadecimal:" +msgstr "Hexadecimaal:" + +#: qalculateconvertunitsdialog.cpp:44 +msgid "Selector" +msgstr "Keuze" + +#: qalculateconvertunitsdialog.cpp:50 qalculateeditdatasetdialog.cpp:482 +msgid "Unit expression:" +msgstr "Eenheidexpressie:" + +#: qalculateconvertunitsdialog.cpp:63 qalculatefunctionsdialog.cpp:55 +#: qalculateunitsdialog.cpp:63 qalculatevariablesdialog.cpp:57 +msgid "Category" +msgstr "Categorie" + +#: qalculateconvertunitsdialog.cpp:85 qalculateconvertunitsdialog.cpp:86 +#: qalculateconvertunitsdialog.cpp:141 qalculateconvertunitsdialog.cpp:180 +#: qalculatefunctionsdialog.cpp:118 qalculatefunctionsdialog.cpp:119 +#: qalculatefunctionsdialog.cpp:183 qalculatefunctionsdialog.cpp:505 +#: qalculateunitsdialog.cpp:150 qalculateunitsdialog.cpp:151 +#: qalculateunitsdialog.cpp:215 qalculateunitsdialog.cpp:416 +#: qalculatevariablesdialog.cpp:116 qalculatevariablesdialog.cpp:117 +#: qalculatevariablesdialog.cpp:183 qalculatevariablesdialog.cpp:462 +msgid "All" +msgstr "Alles" + +#: qalculateconvertunitsdialog.cpp:132 qalculateconvertunitsdialog.cpp:133 +#: qalculateconvertunitsdialog.cpp:134 qalculateconvertunitsdialog.cpp:182 +#: qalculatefunctionsdialog.cpp:165 qalculatefunctionsdialog.cpp:166 +#: qalculatefunctionsdialog.cpp:167 qalculatefunctionsdialog.cpp:236 +#: qalculatefunctionsdialog.cpp:262 qalculatefunctionsdialog.cpp:285 +#: qalculatefunctionsdialog.cpp:507 qalculateunitsdialog.cpp:197 +#: qalculateunitsdialog.cpp:198 qalculateunitsdialog.cpp:199 +#: qalculateunitsdialog.cpp:273 qalculateunitsdialog.cpp:299 +#: qalculateunitsdialog.cpp:322 qalculateunitsdialog.cpp:418 +#: qalculatevariablesdialog.cpp:165 qalculatevariablesdialog.cpp:166 +#: qalculatevariablesdialog.cpp:167 qalculatevariablesdialog.cpp:258 +#: qalculatevariablesdialog.cpp:284 qalculatevariablesdialog.cpp:322 +#: qalculatevariablesdialog.cpp:464 +msgid "Uncategorized" +msgstr "Niet-gecategoriseerd" + +#: qalculatedatasetsdialog.cpp:46 qalculateeditdatasetdialog.cpp:232 +msgid "Data Sets" +msgstr "Gegevensverzamelingen" + +#: qalculatedatasetsdialog.cpp:61 +msgid "Data Sets:" +msgstr "Gegevensverzamelingen:" + +#: qalculatedatasetsdialog.cpp:68 qalculatedatasetsdialog.cpp:91 +#: qalculateeditdatasetdialog.cpp:107 qalculateeditdatasetdialog.cpp:629 +#: qalculateeditfunctiondialog.cpp:133 qalculateeditfunctiondialog.cpp:492 +#: qalculateeditnamesdialog.cpp:64 qalculatefunctionsdialog.cpp:67 +#: qalculateunitsdialog.cpp:91 qalculatevariablesdialog.cpp:66 +msgid "New" +msgstr "Nieuw" + +#: qalculatedatasetsdialog.cpp:77 qalculateeditdatasetdialog.cpp:79 +#: qalculateeditdatasetdialog.cpp:456 qalculateeditfunctiondialog.cpp:98 +msgid "Description:" +msgstr "Beschrijving:" + +#: qalculatedatasetsdialog.cpp:84 +msgid "Objects:" +msgstr "Objecten:" + +#: qalculatedatasetsdialog.cpp:87 qalculateeditdatasetdialog.cpp:236 +#: qalculateeditfunctiondialog.cpp:598 +msgid "Object" +msgstr "Object" + +#: qalculatedatasetsdialog.cpp:100 +msgid "Attributes:" +msgstr "Attributen:" + +#: qalculatedatasetsdialog.cpp:157 qalculatedatasetsdialog.cpp:218 +msgid "Data set does not exist anymore." +msgstr "Gegevensverzameling bestaat niet meer." + +#: qalculatedatasetsdialog.cpp:300 qalculateeditdatasetdialog.cpp:195 +#: qalculatefunctionsdialog.cpp:456 +msgid "key" +msgstr "sleutelwaarde" + +#: qalculatedatasetsdialog.cpp:316 +msgid "Data Retrieval Function" +msgstr "Functie voor ophalen gegevens" + +#: qalculatedecimalsdialog.cpp:31 +msgid "Max decimals:" +msgstr "Max decimalen:" + +#: qalculatedecimalsdialog.cpp:39 +msgid "Min decimals:" +msgstr "Min decimalen:" + +#: qalculateeditdataobjectdialog.cpp:30 qalculateeditdataobjectdialog.cpp:40 +msgid "Edit Object" +msgstr "Object bewerken" + +#: qalculateeditdataobjectdialog.cpp:42 +msgid "New Object" +msgstr "Nieuw object" + +#: qalculateeditdataobjectdialog.cpp:48 qalculateeditdatasetdialog.cpp:242 +msgid "Property" +msgstr "Eigenschap" + +#. i18n: file ./qalculate_kdeui.rc line 116 +#: qalculateeditdataobjectdialog.cpp:51 rc.cpp:39 +#, no-c-format +msgid "Approximation" +msgstr "Benadering" + +#: qalculateeditdatasetdialog.cpp:53 qalculateeditdatasetdialog.cpp:307 +msgid "Edit Data Set" +msgstr "Gegevensverzameling bewerken" + +#: qalculateeditdatasetdialog.cpp:68 qalculateeditfunctiondialog.cpp:70 +#: qalculatepreferencesdialog.cpp:157 +msgid "General" +msgstr "Algemeen" + +#: qalculateeditdatasetdialog.cpp:73 qalculateplotdialog.cpp:86 +#: qalculateplotdialog.cpp:189 +msgid "Title:" +msgstr "Titel:" + +#: qalculateeditdatasetdialog.cpp:76 +msgid "Data file:" +msgstr "Gegevensbestand:" + +#: qalculateeditdatasetdialog.cpp:87 +msgid "Copyright:" +msgstr "Copyright:" + +#: qalculateeditdatasetdialog.cpp:97 +msgid "Properties:" +msgstr "Eigenschappen:" + +#: qalculateeditdatasetdialog.cpp:99 qalculateplotdialog.cpp:153 +msgid "Title" +msgstr "Titel" + +#: qalculateeditdatasetdialog.cpp:100 qalculateeditdatasetdialog.cpp:620 +#: qalculateeditfunctiondialog.cpp:124 qalculateeditnamesdialog.cpp:41 +#: qalculateeditunitdialog.cpp:50 +msgid "Name" +msgstr "Naam" + +#: qalculateeditdatasetdialog.cpp:101 qalculateeditfunctiondialog.cpp:125 +#: qalculateeditunitdialog.cpp:75 qalculateeditunknownvariabledialog.cpp:60 +msgid "Type" +msgstr "Type" + +#: qalculateeditdatasetdialog.cpp:115 qalculateeditdatasetdialog.cpp:442 +#: qalculateeditfunctiondialog.cpp:74 qalculateeditfunctiondialog.cpp:583 +#: qalculateeditmatrixvectordialog.cpp:78 qalculateeditunitdialog.cpp:55 +#: qalculateeditunknownvariabledialog.cpp:47 +#: qalculateeditvariabledialog.cpp:49 qalculateimportcsvdialog.cpp:60 +msgid "Name:" +msgstr "Naam:" + +#: qalculateeditdatasetdialog.cpp:124 qalculateeditdatasetdialog.cpp:451 +#: qalculateeditfunctiondialog.cpp:83 qalculateeditmatrixvectordialog.cpp:87 +#: qalculateeditunitdialog.cpp:64 qalculateeditunknownvariabledialog.cpp:56 +#: qalculateeditvariabledialog.cpp:60 +msgid "Names Details" +msgstr "Namen van onderdelen" + +#: qalculateeditdatasetdialog.cpp:126 +msgid "Object argument name:" +msgstr "Naam objectargument:" + +#: qalculateeditdatasetdialog.cpp:129 +msgid "Property argument name:" +msgstr "Naam eigenschapargument:" + +#: qalculateeditdatasetdialog.cpp:132 +msgid "Default property:" +msgstr "Standaard eigenschap:" + +#: qalculateeditdatasetdialog.cpp:173 +msgid "text" +msgstr "tekst" + +#: qalculateeditdatasetdialog.cpp:178 qalculateeditdatasetdialog.cpp:186 +msgid "approximate" +msgstr "benaderd" + +#: qalculateeditdatasetdialog.cpp:181 qalculateexpressionedit.cpp:712 +#: qalculatevariablesdialog.cpp:428 +msgid "number" +msgstr "getal" + +#: qalculateeditdatasetdialog.cpp:189 +msgid "expression" +msgstr "expressie" + +#: qalculateeditdatasetdialog.cpp:213 qalculateeditdatasetdialog.cpp:499 +#: qalculateeditfunctiondialog.cpp:190 qalculateeditmatrixvectordialog.cpp:185 +#: qalculateeditunitdialog.cpp:146 qalculateeditunknownvariabledialog.cpp:132 +#: qalculateeditvariabledialog.cpp:102 +msgid "Empty name field" +msgstr "Naamveld is leeg" + +#: qalculateeditdatasetdialog.cpp:217 qalculateeditfunctiondialog.cpp:201 +msgid "" +"A function with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" +"Een functie met deze naam bestaat reeds.\n" +"Wilt u die overschrijven?" + +#: qalculateeditdatasetdialog.cpp:309 +msgid "Edit Data Set (global)" +msgstr "Gegevensverzameling bewerken (globaal)" + +#: qalculateeditdatasetdialog.cpp:311 +msgid "New Data Set" +msgstr "Nieuwe gegevensverzameling" + +#: qalculateeditdatasetdialog.cpp:322 +msgid "info" +msgstr "info" + +#: qalculateeditdatasetdialog.cpp:435 qalculateeditdatasetdialog.cpp:548 +msgid "Edit Property" +msgstr "Eigenschap bewerken" + +#: qalculateeditdatasetdialog.cpp:453 qalculateeditfunctiondialog.cpp:90 +#: qalculateeditmatrixvectordialog.cpp:93 qalculateeditunitdialog.cpp:66 +#: qalculateeditunknownvariabledialog.cpp:90 +#: qalculateeditvariabledialog.cpp:80 qalculateimportcsvdialog.cpp:63 +msgid "Descriptive name:" +msgstr "Beschrijvende naam:" + +#: qalculateeditdatasetdialog.cpp:464 +msgid "Value type:" +msgstr "Waardetype:" + +#: qalculateeditdatasetdialog.cpp:467 qalculateeditfunctiondialog.cpp:593 +msgid "Text" +msgstr "Tekst" + +#: qalculateeditdatasetdialog.cpp:469 qalculateeditfunctiondialog.cpp:482 +#: qalculateplotdialog.cpp:154 +msgid "Expression" +msgstr "Expressie" + +#: qalculateeditdatasetdialog.cpp:474 +msgid "Use as key" +msgstr "Gebruiken als toets" + +#: qalculateeditdatasetdialog.cpp:476 +msgid "Approximate value" +msgstr "Benaderde waarde" + +#: qalculateeditdatasetdialog.cpp:478 +msgid "Case sensitive value" +msgstr "Hoofdlettergevoelige waarde" + +#: qalculateeditdatasetdialog.cpp:480 +msgid "Value uses brackets" +msgstr "Waarde met vierkante haakjes" + +#: qalculateeditdatasetdialog.cpp:550 +msgid "New Property" +msgstr "Nieuwe eigenschap" + +#: qalculateeditdatasetdialog.cpp:615 qalculateeditnamesdialog.cpp:34 +msgid "Edit Names" +msgstr "Namen bewerken" + +#: qalculateeditdatasetdialog.cpp:621 qalculateeditfunctiondialog.cpp:481 +#: qalculateeditnamesdialog.cpp:46 +msgid "Reference" +msgstr "Referentie" + +#: qalculateeditfunctiondialog.cpp:55 qalculateeditfunctiondialog.cpp:286 +msgid "Edit Function" +msgstr "Functie bewerken" + +#: qalculateeditfunctiondialog.cpp:85 qalculateeditmatrixvectordialog.cpp:89 +#: qalculateeditunitdialog.cpp:87 qalculateeditunknownvariabledialog.cpp:85 +#: qalculateeditvariabledialog.cpp:74 qalculateimportcsvdialog.cpp:66 +msgid "Category:" +msgstr "Categorie:" + +#: qalculateeditfunctiondialog.cpp:96 +msgid "Hide function" +msgstr "Functie verbergen" + +#: qalculateeditfunctiondialog.cpp:106 qalculateplotdialog.cpp:89 +msgid "Expression:" +msgstr "Expressie:" + +#: qalculateeditfunctiondialog.cpp:115 +msgid "Condition:" +msgstr "Conditie:" + +#: qalculateeditfunctiondialog.cpp:120 qalculateeditfunctiondialog.cpp:476 +msgid "Sub-Functions" +msgstr "Subfuncties" + +#: qalculateeditfunctiondialog.cpp:122 +msgid "Arguments:" +msgstr "Argumenten:" + +#: qalculateeditfunctiondialog.cpp:197 +msgid "Empty expression field" +msgstr "Expressieveld is leeg" + +#: qalculateeditfunctiondialog.cpp:288 +msgid "Edit Function (global)" +msgstr "Functie bewerken (globaal)" + +#: qalculateeditfunctiondialog.cpp:290 +msgid "New Function" +msgstr "Nieuwe functie" + +#: qalculateeditfunctiondialog.cpp:483 +msgid "Precalculate" +msgstr "Voorberekenen" + +#: qalculateeditfunctiondialog.cpp:579 qalculateeditfunctiondialog.cpp:675 +msgid "Edit Argument" +msgstr "Argument bewerken" + +#: qalculateeditfunctiondialog.cpp:586 +msgid "Type:" +msgstr "Type:" + +#: qalculateeditfunctiondialog.cpp:589 +msgid "Free" +msgstr "Vrij" + +#: qalculateeditfunctiondialog.cpp:592 +msgid "Symbol" +msgstr "Symbool" + +#: qalculateeditfunctiondialog.cpp:594 qalculateinsertfunctiondialog.cpp:353 +msgid "Date" +msgstr "Datum" + +#: qalculateeditfunctiondialog.cpp:597 +msgid "Boolean" +msgstr "Booleaans" + +#: qalculateeditfunctiondialog.cpp:603 +msgid "Angle" +msgstr "Hoek" + +#: qalculateeditfunctiondialog.cpp:605 +msgid "Enable rules and type test" +msgstr "Test voor regels en type toestaan" + +#: qalculateeditfunctiondialog.cpp:607 +msgid "Custom condition:" +msgstr "Aangepaste conditie:" + +#: qalculateeditfunctiondialog.cpp:611 +msgid "Allow matrix" +msgstr "Matrix toestaan" + +#: qalculateeditfunctiondialog.cpp:613 +msgid "Forbid zero" +msgstr "Nul niet toestaan" + +#: qalculateeditfunctiondialog.cpp:615 +msgid "Allow complex" +msgstr "Complex toestaan" + +#: qalculateeditfunctiondialog.cpp:617 qalculateplotdialog.cpp:164 +msgid "Min:" +msgstr "Min:" + +#: qalculateeditfunctiondialog.cpp:624 qalculateeditfunctiondialog.cpp:633 +msgid "Include equals" +msgstr "Ook is gelijk aan" + +#: qalculateeditfunctiondialog.cpp:626 qalculateplotdialog.cpp:167 +msgid "Max:" +msgstr "Max:" + +#: qalculateeditfunctiondialog.cpp:677 +msgid "New Argument" +msgstr "Nieuw argument" + +#: qalculateeditmatrixvectordialog.cpp:71 +#: qalculateeditunknownvariabledialog.cpp:40 +#: qalculateeditvariabledialog.cpp:41 qalculateeditvariabledialog.cpp:180 +#: qalculateinsertmatrixvectordialog.cpp:71 +msgid "Edit Variable" +msgstr "Variabele bewerken" + +#: qalculateeditmatrixvectordialog.cpp:96 +#: qalculateinsertmatrixvectordialog.cpp:75 +msgid "Rows:" +msgstr "Rijen:" + +#: qalculateeditmatrixvectordialog.cpp:99 +#: qalculateinsertmatrixvectordialog.cpp:78 +msgid "Columns:" +msgstr "Kolommen:" + +#: qalculateeditmatrixvectordialog.cpp:112 +#: qalculateeditmatrixvectordialog.cpp:133 +#: qalculateeditmatrixvectordialog.cpp:295 +#: qalculateinsertmatrixvectordialog.cpp:91 +#: qalculateinsertmatrixvectordialog.cpp:115 +#: qalculateinsertmatrixvectordialog.cpp:275 +msgid "Elements:" +msgstr "Elementen:" + +#: qalculateeditmatrixvectordialog.cpp:146 +#: qalculateeditmatrixvectordialog.cpp:292 +#: qalculateinsertmatrixvectordialog.cpp:128 +#: qalculateinsertmatrixvectordialog.cpp:272 +msgid "Elements (in horizontal order):" +msgstr "Elementen (horizontale volgorde):" + +#: qalculateeditmatrixvectordialog.cpp:189 +#: qalculateeditunknownvariabledialog.cpp:136 +#: qalculateeditvariabledialog.cpp:114 +msgid "" +"An unit or variable with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" +"Er bestaat al een eenheid of variabele met deze naam.\n" +"Wilt u die overschrijven?" + +#: qalculateeditmatrixvectordialog.cpp:301 +msgid "Edit Vector" +msgstr "Vector bewerken" + +#: qalculateeditmatrixvectordialog.cpp:303 +msgid "Edit Vector (global)" +msgstr "Vector bewerken (globaal)" + +#: qalculateeditmatrixvectordialog.cpp:305 +msgid "New Vector" +msgstr "Nieuwe vector" + +#: qalculateeditmatrixvectordialog.cpp:310 +msgid "Edit Matrix" +msgstr "Matrix bewerken" + +#: qalculateeditmatrixvectordialog.cpp:312 +msgid "Edit Matrix (global)" +msgstr "Matrix bewerken (globaal)" + +#: qalculateeditmatrixvectordialog.cpp:314 +msgid "New Matrix" +msgstr "Nieuwe matrix" + +#: qalculateeditnamesdialog.cpp:42 +msgid "Abbreviation" +msgstr "Afkorting" + +#: qalculateeditnamesdialog.cpp:44 +msgid "Plural" +msgstr "Meervoud" + +#: qalculateeditnamesdialog.cpp:48 +msgid "Avoid Input" +msgstr "Invoer vermijden" + +#: qalculateeditnamesdialog.cpp:50 +msgid "Unicode" +msgstr "Unicode" + +#: qalculateeditnamesdialog.cpp:52 +msgid "Suffix" +msgstr "Achtervoegsel" + +#: qalculateeditnamesdialog.cpp:54 +msgid "Case Sensitive" +msgstr "Hoofdlettergevoelig" + +#: qalculateeditunitdialog.cpp:43 qalculateeditunitdialog.cpp:287 +msgid "Edit Unit" +msgstr "Eenheid bewerken" + +#: qalculateeditunitdialog.cpp:72 +msgid "Hide unit" +msgstr "Eenheid verbergen" + +#: qalculateeditunitdialog.cpp:80 +msgid "Class:" +msgstr "Klasse:" + +#: qalculateeditunitdialog.cpp:83 +msgid "Base Unit" +msgstr "Basiseenheid" + +#: qalculateeditunitdialog.cpp:84 +msgid "Alias" +msgstr "Alias" + +#: qalculateeditunitdialog.cpp:85 +msgid "Composite Unit" +msgstr "Samengestelde eenheid" + +#: qalculateeditunitdialog.cpp:92 +msgid "System:" +msgstr "Systeem:" + +#: qalculateeditunitdialog.cpp:95 +msgid "SI" +msgstr "SI" + +#: qalculateeditunitdialog.cpp:96 +msgid "CGS" +msgstr "CGS" + +#: qalculateeditunitdialog.cpp:97 +msgid "Imperial" +msgstr "Imperial" + +#: qalculateeditunitdialog.cpp:98 +msgid "US Survey" +msgstr "US Survey" + +#: qalculateeditunitdialog.cpp:102 +msgid "Relation" +msgstr "Relatie" + +#: qalculateeditunitdialog.cpp:107 +msgid "Base unit:" +msgstr "Basiseenheid:" + +#: qalculateeditunitdialog.cpp:110 +msgid "Exponent:" +msgstr "Exponent:" + +#: qalculateeditunitdialog.cpp:114 +msgid "Relation:" +msgstr "Relatie:" + +#: qalculateeditunitdialog.cpp:121 +msgid "Relation is exact" +msgstr "Relatie is exact" + +#: qalculateeditunitdialog.cpp:123 +msgid "Inverse relation:" +msgstr "Inverse relatie:" + +#: qalculateeditunitdialog.cpp:150 +msgid "" +"A variable or unit with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" +"Er bestaat al een variabele of eenheid met deze naam.\n" +"Wilt u die overschrijven?" + +#: qalculateeditunitdialog.cpp:175 qalculateeditunitdialog.cpp:219 +msgid "Base unit does not exist" +msgstr "Basiseenheid bestaat niet" + +#: qalculateeditunitdialog.cpp:289 +msgid "Edit Unit (global)" +msgstr "Eenheid bewerken (globaal)" + +#: qalculateeditunitdialog.cpp:291 +msgid "New Unit" +msgstr "Nieuwe eenheid" + +#: qalculateeditunknownvariabledialog.cpp:58 +msgid "Custom assumptions:" +msgstr "Aangepaste aannames:" + +#: qalculateeditunknownvariabledialog.cpp:68 +msgid "Complex Number" +msgstr "Complex getal" + +#: qalculateeditunknownvariabledialog.cpp:69 +msgid "Real Number" +msgstr "Reëel getal" + +#: qalculateeditunknownvariabledialog.cpp:70 +msgid "Rational Number" +msgstr "Rationaal getal" + +#: qalculateeditunknownvariabledialog.cpp:73 +msgid "Sign" +msgstr "Teken" + +#: qalculateeditunknownvariabledialog.cpp:199 +msgid "Edit Unknown Variable" +msgstr "Onbekende variabele bewerken" + +#: qalculateeditunknownvariabledialog.cpp:201 +msgid "Edit Unknown Variable (global)" +msgstr "Onbekende variabele bewerken (globaal)" + +#: qalculateeditunknownvariabledialog.cpp:203 +msgid "New Unknown Variable" +msgstr "Nieuwe onbekende variabele" + +#: qalculateeditvariabledialog.cpp:63 qalculateinsertfunctiondialog.cpp:91 +msgid "Value:" +msgstr "Waarde:" + +#: qalculateeditvariabledialog.cpp:71 +msgid "Value is exact" +msgstr "Waarde is exact" + +#: qalculateeditvariabledialog.cpp:110 +msgid "Empty value field" +msgstr "Waardeveld is leeg" + +#: qalculateeditvariabledialog.cpp:182 +msgid "Edit Variable (global)" +msgstr "Variabele bewerken (globaal)" + +#: qalculateeditvariabledialog.cpp:185 +msgid "New Variable" +msgstr "Nieuwe variabele" + +#: qalculateexportcsvdialog.cpp:37 qalculateexportcsvdialog.cpp:54 +msgid "Export CSV File" +msgstr "CSV-bestand exporteren" + +#: qalculateexportcsvdialog.cpp:42 +msgid "Current result" +msgstr "Huidig antwoord" + +#: qalculateexportcsvdialog.cpp:46 +msgid "Matrix/vector variable" +msgstr "Matrix/vector-variabele" + +#: qalculateexportcsvdialog.cpp:51 qalculateimportcsvdialog.cpp:43 +msgid "File:" +msgstr "Bestand:" + +#: qalculateexportcsvdialog.cpp:56 qalculateimportcsvdialog.cpp:80 +msgid "Delimiter:" +msgstr "Scheidingsteken:" + +#: qalculateexportcsvdialog.cpp:59 qalculateimportcsvdialog.cpp:83 +msgid "Comma" +msgstr "Komma" + +#: qalculateexportcsvdialog.cpp:60 qalculateimportcsvdialog.cpp:84 +msgid "Tabulator" +msgstr "Tabtoets" + +#: qalculateexportcsvdialog.cpp:61 qalculateimportcsvdialog.cpp:85 +msgid "Semicolon" +msgstr "Puntkomma" + +#: qalculateexportcsvdialog.cpp:62 qalculateimportcsvdialog.cpp:86 +msgid "Space" +msgstr "Spatie" + +#: qalculateexportcsvdialog.cpp:63 qalculateimportcsvdialog.cpp:87 +msgid "Other" +msgstr "Overig" + +#: qalculateexportcsvdialog.cpp:93 qalculateimportcsvdialog.cpp:116 +msgid "No file name entered." +msgstr "Geen bestandsnaam opgegeven." + +#: qalculateexportcsvdialog.cpp:122 qalculateimportcsvdialog.cpp:145 +msgid "No delimiter selected." +msgstr "Geen scheidingsteken geselecteerd." + +#: qalculateexportcsvdialog.cpp:135 +msgid "No variable name entered." +msgstr "Geen naam opgegeven voor variabele." + +#: qalculateexportcsvdialog.cpp:147 +msgid "No known variable with entered name found." +msgstr "Geen bekende variabele met opgegeven naam gevonden." + +#: qalculateexportcsvdialog.cpp:154 +#, c-format +msgid "" +"Could not export to file \n" +"%s" +msgstr "" +"Kon niet exporteren naar bestand \n" +"%s" + +#: qalculateexpressionedit.cpp:146 +msgid "Disable Completion" +msgstr "Voltooien uitschakelen" + +#: qalculateexpressionedit.cpp:147 +msgid "Enable Completion" +msgstr "Voltooien toestaan" + +#. i18n: file ./qalculate_kdeui.rc line 154 +#: qalculateexpressionedit.cpp:161 qalculateresultdisplay.cpp:333 rc.cpp:48 +#, no-c-format +msgid "Meta Modes" +msgstr "Metamodes" + +#: qalculateexpressionedit.cpp:655 qalculatevariablesdialog.cpp:366 +msgid "a previous result" +msgstr "een vorig antwoord" + +#: qalculateexpressionedit.cpp:661 qalculatevariablesdialog.cpp:376 +msgid "matrix" +msgstr "matrix" + +#: qalculateexpressionedit.cpp:663 qalculatevariablesdialog.cpp:378 +msgid "vector" +msgstr "vector" + +#: qalculateexpressionedit.cpp:672 qalculatevariablesdialog.cpp:387 +msgid "positive" +msgstr "positief" + +#: qalculateexpressionedit.cpp:676 qalculatevariablesdialog.cpp:391 +msgid "non-positive" +msgstr "Niet-positief" + +#: qalculateexpressionedit.cpp:680 qalculatevariablesdialog.cpp:395 +msgid "negative" +msgstr "negatief" + +#: qalculateexpressionedit.cpp:684 qalculatevariablesdialog.cpp:399 +msgid "non-negative" +msgstr "niet-negatief" + +#: qalculateexpressionedit.cpp:688 qalculatevariablesdialog.cpp:403 +msgid "non-zero" +msgstr "ongelijk nul" + +#: qalculateexpressionedit.cpp:696 qalculatevariablesdialog.cpp:412 +msgid "integer" +msgstr "geheel" + +#: qalculateexpressionedit.cpp:700 qalculatevariablesdialog.cpp:416 +msgid "rational" +msgstr "rationaal" + +#: qalculateexpressionedit.cpp:704 qalculatevariablesdialog.cpp:420 +msgid "real" +msgstr "reëel" + +#: qalculateexpressionedit.cpp:708 qalculatevariablesdialog.cpp:424 +msgid "complex" +msgstr "complex" + +#: qalculateexpressionedit.cpp:716 qalculatevariablesdialog.cpp:432 +msgid "(not matrix)" +msgstr "(geen matrix)" + +#: qalculateexpressionedit.cpp:721 qalculatevariablesdialog.cpp:438 +msgid "unknown" +msgstr "onbekende" + +#: qalculateexpressionedit.cpp:723 qalculatevariablesdialog.cpp:440 +msgid "default assumptions" +msgstr "standaard aannames" + +#: qalculatefunctionsdialog.cpp:47 +msgid "Functions" +msgstr "Functies" + +#: qalculatefunctionsdialog.cpp:59 +msgid "Function Name" +msgstr "Functienaam" + +#: qalculatefunctionsdialog.cpp:75 qalculatefunctionsdialog.cpp:313 +#: qalculateunitsdialog.cpp:99 qalculateunitsdialog.cpp:352 +#: qalculatevariablesdialog.cpp:74 qalculatevariablesdialog.cpp:349 +msgid "Deactivate" +msgstr "Uitschakelen" + +#: qalculatefunctionsdialog.cpp:174 qalculatefunctionsdialog.cpp:175 +#: qalculatefunctionsdialog.cpp:176 qalculatefunctionsdialog.cpp:234 +#: qalculatefunctionsdialog.cpp:260 qalculatefunctionsdialog.cpp:283 +#: qalculatefunctionsdialog.cpp:509 qalculateunitsdialog.cpp:206 +#: qalculateunitsdialog.cpp:207 qalculateunitsdialog.cpp:208 +#: qalculateunitsdialog.cpp:271 qalculateunitsdialog.cpp:297 +#: qalculateunitsdialog.cpp:320 qalculateunitsdialog.cpp:420 +#: qalculatevariablesdialog.cpp:174 qalculatevariablesdialog.cpp:175 +#: qalculatevariablesdialog.cpp:176 qalculatevariablesdialog.cpp:256 +#: qalculatevariablesdialog.cpp:282 qalculatevariablesdialog.cpp:320 +#: qalculatevariablesdialog.cpp:466 +msgid "Inactive" +msgstr "Inactief" + +#: qalculatefunctionsdialog.cpp:315 qalculateunitsdialog.cpp:354 +#: qalculatevariablesdialog.cpp:351 +msgid "Activate" +msgstr "Activeren" + +#: qalculatefunctionsdialog.cpp:367 qalculateresultdisplay.cpp:148 +#, c-format +msgid "" +"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." +msgstr "" +"Haalt gegevens op van een gegeven object of eigenschap uit de " +"gegevensverzameling %s. Indien als eigenschap \"info\" wordt ingetypt krijgt " +"u een dialoogvenster te zien waarin alle eigenschappen van het object worden " +"genoemd." + +#: qalculatefunctionsdialog.cpp:391 +msgid "Arguments" +msgstr "Argumenten" + +#: qalculatefunctionsdialog.cpp:412 qalculateinsertfunctiondialog.cpp:194 +#: qalculateinsertfunctiondialog.cpp:227 +msgid "optional" +msgstr "optioneel" + +#: qalculatefunctionsdialog.cpp:416 +msgid "default: " +msgstr "standaard: " + +#: qalculatefunctionsdialog.cpp:426 +msgid "Requirement" +msgstr "Vereiste" + +#: qalculateimportcsvdialog.cpp:39 qalculateimportcsvdialog.cpp:46 +msgid "Import CSV File" +msgstr "CSV-bestand importeren" + +#: qalculateimportcsvdialog.cpp:48 +msgid "Import as:" +msgstr "Importeren als:" + +#: qalculateimportcsvdialog.cpp:71 +msgid "First row:" +msgstr "Eerste rij:" + +#: qalculateimportcsvdialog.cpp:77 +msgid "Includes headings" +msgstr "Ook de koppen weergegeven" + +#: qalculateimportcsvdialog.cpp:149 +msgid "An error occured when importing the CSV file." +msgstr "Fout bij het importeren van het CSV-bestand." + +#: qalculateinsertfunctiondialog.cpp:50 qalculateinsertfunctiondialog.cpp:57 +msgid "Execute" +msgstr "Uitvoeren" + +#: qalculateinsertfunctiondialog.cpp:93 +msgid "Argument" +msgstr "Argument" + +#: qalculateinsertfunctiondialog.cpp:152 +msgid "True" +msgstr "Waar" + +#: qalculateinsertfunctiondialog.cpp:153 +msgid "False" +msgstr "Onwaar" + +#: qalculateinsertfunctiondialog.cpp:184 +msgid "Info" +msgstr "Info" + +#: qalculateinsertmatrixvectordialog.cpp:71 +msgid "Insert Selection" +msgstr "Selectie invoegen" + +#: qalculateinsertmatrixvectordialog.cpp:293 +msgid "Vector Result" +msgstr "Antwoordvector" + +#: qalculateinsertmatrixvectordialog.cpp:295 +msgid "Matrix Result" +msgstr "Antwoordmatrix" + +#: qalculateperiodictabledialog.cpp:195 +msgid "Element Data" +msgstr "Elementgegevens" + +#: qalculateperiodictabledialog.cpp:221 +msgid "Classification" +msgstr "Indeling" + +#: qalculateperiodictabledialog.cpp:224 +msgid "Alkali Metal" +msgstr "Alkalisch metaal" + +#: qalculateperiodictabledialog.cpp:225 +msgid "Alkaline-Earth Metal" +msgstr "Alkalisch aardmetaal" + +#: qalculateperiodictabledialog.cpp:226 +msgid "Lanthanide" +msgstr "Lanthanide" + +#: qalculateperiodictabledialog.cpp:227 +msgid "Actinide" +msgstr "Actinide" + +#: qalculateperiodictabledialog.cpp:228 +msgid "Transition Metal" +msgstr "Overgangsmetaal" + +#: qalculateperiodictabledialog.cpp:229 +msgid "Metal" +msgstr "Metaal" + +#: qalculateperiodictabledialog.cpp:230 +msgid "Metalloid" +msgstr "Metalloïde (halfmetaal)" + +#: qalculateperiodictabledialog.cpp:231 +msgid "Non-Metal" +msgstr "Niet-metaal" + +#: qalculateperiodictabledialog.cpp:232 +msgid "Halogen" +msgstr "Halogeen" + +#: qalculateperiodictabledialog.cpp:233 +msgid "Noble Gas" +msgstr "Edelgas" + +#: qalculateperiodictabledialog.cpp:234 +msgid "Transactinide" +msgstr "Transactinide" + +#: qalculateplotdialog.cpp:64 +msgid "Plot" +msgstr "Plot" + +#: qalculateplotdialog.cpp:82 +msgid "Data" +msgstr "Gegevens" + +#: qalculateplotdialog.cpp:83 +msgid "Function Range" +msgstr "Functiebereik" + +#: qalculateplotdialog.cpp:101 +msgid "Vector/matrix" +msgstr "Vector/matrix" + +#: qalculateplotdialog.cpp:104 +msgid "Paired matrix" +msgstr "Gepaarde matrix" + +#: qalculateplotdialog.cpp:107 +msgid "Rows" +msgstr "Rijen" + +#: qalculateplotdialog.cpp:109 +msgid "X variable:" +msgstr "Variabele X:" + +#: qalculateplotdialog.cpp:113 +msgid "Style:" +msgstr "Stijl:" + +#: qalculateplotdialog.cpp:115 +msgid "Line" +msgstr "Lijn" + +#: qalculateplotdialog.cpp:116 +msgid "Points" +msgstr "Punten" + +#: qalculateplotdialog.cpp:117 +msgid "Line with points" +msgstr "Lijn met punten" + +#: qalculateplotdialog.cpp:118 +msgid "Boxes/bars" +msgstr "Vakken/balken" + +#: qalculateplotdialog.cpp:119 +msgid "Histogram" +msgstr "Histogram" + +#: qalculateplotdialog.cpp:120 +msgid "Steps" +msgstr "Stappen" + +#: qalculateplotdialog.cpp:121 +msgid "Candlesticks" +msgstr "Kaarsdiagrammen" + +#: qalculateplotdialog.cpp:122 +msgid "Dots" +msgstr "Puntjes" + +#: qalculateplotdialog.cpp:124 +msgid "Smoothing:" +msgstr "Gladstrijken:" + +#: qalculateplotdialog.cpp:127 +msgid "Monotonic" +msgstr "Monotoon" + +#: qalculateplotdialog.cpp:128 +msgid "Natural cubic splines" +msgstr "Natuurlijke kubische splines" + +#: qalculateplotdialog.cpp:129 +msgid "Bezier" +msgstr "Bézier" + +#: qalculateplotdialog.cpp:130 +msgid "Bezier (monotonic)" +msgstr "Bézier (monotoon)" + +#: qalculateplotdialog.cpp:132 +msgid "Y-axis:" +msgstr "Y-as:" + +#: qalculateplotdialog.cpp:136 +msgid "Primary" +msgstr "Primair" + +#: qalculateplotdialog.cpp:139 +msgid "Secondary" +msgstr "Secondair" + +#: qalculateplotdialog.cpp:171 +msgid "Sampling rate:" +msgstr "Monsterfrequentie:" + +#: qalculateplotdialog.cpp:176 +msgid "Step size:" +msgstr "Stapgrootte:" + +#: qalculateplotdialog.cpp:194 +msgid "Display grid" +msgstr "Rooster tonen" + +#: qalculateplotdialog.cpp:196 +msgid "Display full border" +msgstr "Volledige rand tonen" + +#: qalculateplotdialog.cpp:199 +msgid "Logarithmic x scale:" +msgstr "Logaritmische schaal x-as:" + +#: qalculateplotdialog.cpp:203 +msgid "Logarithmic y scale:" +msgstr "Logaritmische schaal y-as:" + +#: qalculateplotdialog.cpp:207 +msgid "X-axis label:" +msgstr "Tekst bij x-as:" + +#: qalculateplotdialog.cpp:210 +msgid "Y-axis label:" +msgstr "Tekst bij y-as:" + +#: qalculateplotdialog.cpp:213 +msgid "Color display:" +msgstr "Kleuren:" + +#: qalculateplotdialog.cpp:217 +msgid "Color" +msgstr "Kleur" + +#: qalculateplotdialog.cpp:220 +msgid "Monochrome" +msgstr "Zwartwit" + +#: qalculateplotdialog.cpp:224 +msgid "Legend placement:" +msgstr "Plaats van legenda:" + +#: qalculateplotdialog.cpp:227 +msgid "Top-left" +msgstr "Linksboven" + +#: qalculateplotdialog.cpp:228 +msgid "Top-right" +msgstr "Rechtsboven" + +#: qalculateplotdialog.cpp:229 +msgid "Bottom-left" +msgstr "Linksonder" + +#: qalculateplotdialog.cpp:230 +msgid "Bottom-right" +msgstr "Rechtsonder" + +#: qalculateplotdialog.cpp:231 +msgid "Below" +msgstr "Onder" + +#: qalculateplotdialog.cpp:232 +msgid "Outside" +msgstr "Er buiten" + +#: qalculateplotdialog.cpp:403 qalculateplotdialog.cpp:458 +#: qalculateplotdialog.cpp:506 +msgid "Empty expression." +msgstr "Expressie niet gegeven." + +#: qalculateplotdialog.cpp:472 qalculateplotdialog.cpp:519 +msgid "Empty x variable." +msgstr "Variabele niet gegeven." + +#: qalculateprecisiondialog.cpp:34 qalculateprecisiondialog.cpp:36 +msgid "Recalculate" +msgstr "Opnieuw berekenen" + +#: qalculateprecisiondialog.cpp:41 +msgid "Precision:" +msgstr "Nauwkeurigheid:" + +#: qalculatepreferencesdialog.cpp:100 +msgid "Choose..." +msgstr "Kiezen..." + +#: qalculatepreferencesdialog.cpp:147 +msgid "Preferences" +msgstr "Voorkeuren" + +#: qalculatepreferencesdialog.cpp:161 +msgid "Close to system tray" +msgstr "Dichtbij systeemvak" + +#: qalculatepreferencesdialog.cpp:162 +msgid "" +"If the application will reside in the system tray when the window is closed" +msgstr "" +"Of de toepassing in het systeemvak moet blijven na het afsluiten van het " +"venster" + +#: qalculatepreferencesdialog.cpp:164 +msgid "Display expression status" +msgstr "Toon expressiestatus" + +#: qalculatepreferencesdialog.cpp:165 +msgid "" +"If as-you-type expression status shall be displayed below the expression " +"entry" +msgstr "" +"Indien status expressie zoals u-die-intypt moet worden getoond onder de " +"invoer van de expressie" + +#: qalculatepreferencesdialog.cpp:167 +msgid "Use icon buttons" +msgstr "Knoppen met pictogrammen gebruiken" + +#: qalculatepreferencesdialog.cpp:168 +msgid "" +"Use icons instead of text on the top-right buttons. The third state uses the " +"style setting for icons on buttons." +msgstr "" +"Gebruik pictogrammen in plaats van tekst voor de knoppen rechtsboven. In de " +"derde toestand worden de stijlinstellingen voor pictogrammen en knoppen " +"gebruikt." + +#: qalculatepreferencesdialog.cpp:171 +msgid "Update exchange rates on start" +msgstr "Wisselkoersen ophalen bij opstarten" + +#: qalculatepreferencesdialog.cpp:172 +msgid "" +"If current exchange rates shall be downloaded from the internet at program " +"start" +msgstr "" +"Of de huidige wisselkoersen moeten worden opgehaald van het internet bij het " +"starten van het programma" + +#: qalculatepreferencesdialog.cpp:174 +msgid "Save mode on exit" +msgstr "Modus opslaan bij verlaten" + +#: qalculatepreferencesdialog.cpp:175 +msgid "If the mode of the calculator shall be restored" +msgstr "Indien de modus van de rekenmachine moet worden teruggezet" + +#: qalculatepreferencesdialog.cpp:177 +msgid "Save definitions on exit" +msgstr "Definities opslaan bij verlaten" + +#: qalculatepreferencesdialog.cpp:178 +msgid "" +"If changes to functions, units and variables shall be saved automatically" +msgstr "" +"Of veranderingen in functies, eenheden en variabelen automatisch moeten " +"worden opgeslagen" + +#: qalculatepreferencesdialog.cpp:180 +msgid "Use only keypad keys for RPN" +msgstr "" +"Gebruik voor RPN alleen de toesten van het numerieke deel van het toetsenbord" + +#: qalculatepreferencesdialog.cpp:181 +msgid "" +"Use only keypad keys for RPN operations (+-*/^) and use the rest of the " +"keyboard for expression entry" +msgstr "" +"Gebruik alleen de toesten op het numerieke deel van het toetsenbord voor RPN-" +"bewerkingen (+-*/^) en gebruik de rest van het toestenbord voor de invoer " +"van expressies" + +#: qalculatepreferencesdialog.cpp:183 +msgid "Ignores dots in numbers" +msgstr "Punten in getallen worden genegeerd" + +#: qalculatepreferencesdialog.cpp:184 +msgid "" +"Allow dots, '.', to be used as thousands separator instead of as an " +"alternative to decimal sign" +msgstr "" +"Toestaan dat punten, '.', worden gebruikt als scheidingsteken voor " +"duizendtallen in plaats van een alternatief decimaal teken" + +#: qalculatepreferencesdialog.cpp:187 +msgid "Enable unicode signs" +msgstr "Unicode toestaan" + +#: qalculatepreferencesdialog.cpp:188 +msgid "Disable this if you have problems with some fancy characters" +msgstr "Dit uitschakelen als er problemen zijn met bijzondere karakters" + +#: qalculatepreferencesdialog.cpp:190 +msgid "Use lower case in numbers" +msgstr "Kleine letters voor getallen gebruiken" + +#: qalculatepreferencesdialog.cpp:191 +msgid "If lower case letters should be used in numbers with non-decimal base" +msgstr "Indien kleine letters moeten worden gebruikt in niet-decimale getallen" + +#: qalculatepreferencesdialog.cpp:193 +msgid "Use lower case \"e\"" +msgstr "Kleine letter \"e\" gebruiken" + +#: qalculatepreferencesdialog.cpp:194 +msgid "If \"e\"; shall be used instead of \"E\" in numbers" +msgstr "Indien in getallen \"e\" moet worden gebruikt in plaats van \"E\"" + +#: qalculatepreferencesdialog.cpp:196 +msgid "Alternative base prefixes" +msgstr "Alternatieve voorvoegsels voor het grondtal" + +#: qalculatepreferencesdialog.cpp:197 +msgid "" +"If hexadecimal numbers shall be displayed with \"0x0\" and binary numbers " +"with \"0b00\" as prefixes" +msgstr "" +"Of hexadecimale getallen worden getoond met het voorvoegsel \"0x0\" en " +"binaire getallen met het voorvoegsel \"0b00\"" + +#: qalculatepreferencesdialog.cpp:199 +msgid "Spell out logical operators" +msgstr "Logische operatoren voluit spellen" + +#: qalculatepreferencesdialog.cpp:200 +msgid "If logical and/or shall be displayed as \"&&\"/\"||\" or \"and\"/\"or\"" +msgstr "" +"Indien logische and/or moeten worden getoond als \"&&\"/\"||\" of als \"and" +"\"/\"or\"" + +#: qalculatepreferencesdialog.cpp:203 +msgid "Multiplication sign:" +msgstr "Vermenigvuldigingsteken:" + +#: qalculatepreferencesdialog.cpp:215 +msgid "Division sign:" +msgstr "Teken voor deling:" + +#: qalculatepreferencesdialog.cpp:230 +msgid "Custom result font" +msgstr "Aangepast lettertype voor antwoord" + +#: qalculatepreferencesdialog.cpp:234 +msgid "Custom expression font" +msgstr "Aangepast lettertype voor expressie" + +#: qalculatepreferencesdialog.cpp:238 +msgid "Custom status font" +msgstr "Aangepast lettertype voor status" + +#: qalculatepreferencesdialog.cpp:243 +msgid "Status error color:" +msgstr "Kleur foutstatus:" + +#: qalculatepreferencesdialog.cpp:250 +msgid "Status warning color:" +msgstr "Kleur waarschuwingstatus:" + +#: qalculateresultdisplay.cpp:52 +msgid "a matrix" +msgstr "een matrix" + +#: qalculateresultdisplay.cpp:54 +msgid "a vector" +msgstr "een vector" + +#: qalculateresultdisplay.cpp:57 +msgid "double-click to view/edit" +msgstr "dubbelklik voor bekijken/bewerken" + +#: qalculateresultdisplay.cpp:60 +msgid "Unknown variable" +msgstr "Onbekende variabele" + +#: qalculateresultdisplay.cpp:72 +msgid "Prefix" +msgstr "Voorvoegsel" + +#: qalculateresultdisplay.cpp:336 +msgid "Show Parsed Expression" +msgstr "Ingelezen functie tonen" + +#: qalculateresultdisplay.cpp:342 qalculateresultdisplay.cpp:353 +msgid "Show Object Info" +msgstr "Informatie over object tonen" + +#: qalculateresultdisplay.cpp:348 +msgid "View/Edit Matrix" +msgstr "Matrix bekijken/bewerken" + +#: qalculateresultdisplay.cpp:350 +msgid "View/Edit Vector" +msgstr "Vector bekijken/bewerken" + +#: qalculateresultdisplay.cpp:382 +msgid "Parsed expression:" +msgstr "Ingelezen expressie:" + +#: qalculatesetbasedialog.cpp:33 +msgid "Result Base" +msgstr "Grondtal van het antwoord" + +#: qalculatesetbasedialog.cpp:39 qalculatesetbasedialog.cpp:52 +msgid "Other:" +msgstr "Overig:" + +#: qalculatesetbasedialog.cpp:43 +msgid "Time format" +msgstr "Tijdnotatie" + +#: qalculatesetbasedialog.cpp:44 qalculatesetbasedialog.cpp:55 +msgid "Roman numerals" +msgstr "Romeinse cijfers" + +#: qalculatesetbasedialog.cpp:46 +msgid "Expression Base" +msgstr "Grondtal van de expressie" + +#: qalculateunitsdialog.cpp:54 +msgid "Units" +msgstr "Eenheden" + +#: qalculateunitsdialog.cpp:68 +msgid "Names" +msgstr "Namen" + +#: qalculateunitsdialog.cpp:69 +msgid "Base" +msgstr "Grondtal" + +#: qalculateunitsdialog.cpp:72 +msgid "Conversion" +msgstr "Conversie" + +#: qalculateunitsdialog.cpp:105 +msgid "Convert Result" +msgstr "Antwoord converteren" + +#: qalculateunitsdialog.cpp:250 +msgid "Cannot delete unit as it is needed by other units." +msgstr "Kan eenheid niet wissen omdat die nodig is voor andere eenheden." + +#: qalculatevariablesdialog.cpp:51 +msgid "Variables" +msgstr "Variabelen" + +#: qalculatevariablesdialog.cpp:60 +msgid "Variable Name" +msgstr "Naam variabele" + +#. i18n: file ./qalculate_kdeui.rc line 5 +#: rc.cpp:6 +#, no-c-format +msgid "&New" +msgstr "&Nieuw" + +#. i18n: file ./qalculate_kdeui.rc line 37 +#: rc.cpp:12 +#, no-c-format +msgid "&Set Prefix" +msgstr "&Voorvoegsel" + +#. i18n: file ./qalculate_kdeui.rc line 39 +#: rc.cpp:15 +#, no-c-format +msgid "&Convert To Unit" +msgstr "&Converteren naar eenheid" + +#. i18n: file ./qalculate_kdeui.rc line 54 +#: rc.cpp:18 +#, no-c-format +msgid "&Mode" +msgstr "&Modus" + +#. i18n: file ./qalculate_kdeui.rc line 55 +#: rc.cpp:21 +#, no-c-format +msgid "Number Base" +msgstr "Grondtal talstelsel" + +#. i18n: file ./qalculate_kdeui.rc line 67 +#: rc.cpp:24 +#, no-c-format +msgid "Numerical Display" +msgstr "Tonen getal" + +#. i18n: file ./qalculate_kdeui.rc line 80 +#: rc.cpp:27 +#, no-c-format +msgid "Fractional Display" +msgstr "Tonen breuk" + +#. i18n: file ./qalculate_kdeui.rc line 86 +#: rc.cpp:30 +#, no-c-format +msgid "Unit Display" +msgstr "Tonen eenheid" + +#. i18n: file ./qalculate_kdeui.rc line 96 +#: rc.cpp:33 +#, no-c-format +msgid "Angle Unit" +msgstr "Hoekeenheid" + +#. i18n: file ./qalculate_kdeui.rc line 104 +#: rc.cpp:36 +#, no-c-format +msgid "Enabled Objects" +msgstr "Ingeschakelde objecten" + +#. i18n: file ./qalculate_kdeui.rc line 121 +#: rc.cpp:42 +#, no-c-format +msgid "Assumptions" +msgstr "Aannames" + +#. i18n: file ./qalculate_kdeui.rc line 137 +#: rc.cpp:45 +#, no-c-format +msgid "Algebraic Mode" +msgstr "Algebraïsche modus" + +#. i18n: file ./qalculate_kdeui.rc line 161 +#: rc.cpp:51 +#, no-c-format +msgid "Fu&nctions" +msgstr "Fu&ncties" + +#. i18n: file ./qalculate_kdeui.rc line 163 +#: rc.cpp:54 +#, no-c-format +msgid "&Variables" +msgstr "&Variabelen" + +#. i18n: file ./qalculate_kdeui.rc line 165 +#: rc.cpp:57 +#, no-c-format +msgid "&Units" +msgstr "&Eenheden" diff --git a/po/qalculate_kde.pot b/po/qalculate_kde.pot new file mode 100644 index 0000000..4f9b462 --- /dev/null +++ b/po/qalculate_kde.pot @@ -0,0 +1,2587 @@ +# SOME DESCRIPTIVE TITLE. +# This file is put in the public domain. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-05-08 14:44+0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: _translatorinfo.cpp:1 +msgid "" +"_: NAME OF TRANSLATORS\n" +"Your names" +msgstr "" + +#: _translatorinfo.cpp:3 +msgid "" +"_: EMAIL OF TRANSLATORS\n" +"Your emails" +msgstr "" + +#: kqalculate.cpp:264 +msgid "Remove from System Tray" +msgstr "" + +#: kqalculate.cpp:265 qalculateeditdatasetdialog.cpp:471 +#: qalculateplotdialog.cpp:226 +msgid "Hide" +msgstr "" + +#: kqalculate.cpp:286 kqalculate.cpp:4484 kqalculate.cpp:5915 +msgid "Enter" +msgstr "" + +#: kqalculate.cpp:287 kqalculate.cpp:513 kqalculate.cpp:4485 +#: kqalculate.cpp:4492 kqalculate.cpp:5916 +msgid "=" +msgstr "" + +#: kqalculate.cpp:289 kqalculate.cpp:514 kqalculate.cpp:4489 +#: kqalculate.cpp:4490 +msgid "Calculate expression and add to stack" +msgstr "" + +#: kqalculate.cpp:290 kqalculate.cpp:515 kqalculate.cpp:4493 +#: kqalculate.cpp:4494 +msgid "Calculate expression" +msgstr "" + +#: kqalculate.cpp:296 kqalculate.cpp:5918 +msgid "Store" +msgstr "" + +#: kqalculate.cpp:298 +msgid "Store result as variable" +msgstr "" + +#: kqalculate.cpp:301 kqalculate.cpp:5920 qalculateconvertunitsdialog.cpp:42 +msgid "Convert" +msgstr "" + +#: kqalculate.cpp:303 +msgid "Convert units in result" +msgstr "" + +#: kqalculate.cpp:313 +msgid "Enter expression here" +msgstr "" + +#: kqalculate.cpp:322 +msgid "status" +msgstr "" + +#: kqalculate.cpp:354 qalculateeditdataobjectdialog.cpp:71 +msgid "Exact" +msgstr "" + +#: kqalculate.cpp:355 +msgid "Toggle exact mode" +msgstr "" + +#: kqalculate.cpp:358 kqalculate.cpp:1070 +msgid "Fraction" +msgstr "" + +#: kqalculate.cpp:359 +msgid "Toggle fractional display" +msgstr "" + +#: kqalculate.cpp:363 +msgid "Numerical display" +msgstr "" + +#: kqalculate.cpp:366 kqalculate.cpp:1046 qalculateresultdisplay.cpp:288 +msgid "Normal" +msgstr "" + +#: kqalculate.cpp:367 kqalculate.cpp:1048 qalculateresultdisplay.cpp:291 +msgid "Engineering" +msgstr "" + +#: kqalculate.cpp:368 kqalculate.cpp:1050 qalculateresultdisplay.cpp:294 +msgid "Scientific" +msgstr "" + +#: kqalculate.cpp:369 +msgid "Pure" +msgstr "" + +#: kqalculate.cpp:370 kqalculate.cpp:1054 +msgid "Simple" +msgstr "" + +#: kqalculate.cpp:372 +msgid "Base in result" +msgstr "" + +#: kqalculate.cpp:376 kqalculate.cpp:1029 qalculatesetbasedialog.cpp:35 +#: qalculatesetbasedialog.cpp:48 +msgid "Binary" +msgstr "" + +#: kqalculate.cpp:377 kqalculate.cpp:1031 qalculatesetbasedialog.cpp:36 +#: qalculatesetbasedialog.cpp:49 +msgid "Octal" +msgstr "" + +#: kqalculate.cpp:378 kqalculate.cpp:1033 kqalculate.cpp:1066 +#: qalculatesetbasedialog.cpp:37 qalculatesetbasedialog.cpp:50 +msgid "Decimal" +msgstr "" + +#: kqalculate.cpp:379 kqalculate.cpp:1035 qalculatesetbasedialog.cpp:38 +#: qalculatesetbasedialog.cpp:51 +msgid "Hexadecimal" +msgstr "" + +#: kqalculate.cpp:380 kqalculate.cpp:1039 qalculatesetbasedialog.cpp:42 +msgid "Sexagesimal" +msgstr "" + +#: kqalculate.cpp:381 kqalculate.cpp:1041 +msgid "Time Format" +msgstr "" + +#: kqalculate.cpp:383 kqalculate.cpp:1037 +msgid "Other..." +msgstr "" + +#: kqalculate.cpp:389 +msgid "f(x)" +msgstr "" + +#: kqalculate.cpp:393 +msgid "Open functions manager" +msgstr "" + +#: kqalculate.cpp:395 +msgid "sqrt" +msgstr "" + +#: kqalculate.cpp:396 +msgid "Square root" +msgstr "" + +#: kqalculate.cpp:399 kqalculate.cpp:947 +msgid "xy" +msgstr "" + +#: kqalculate.cpp:400 +msgid "Raise (Ctrl+*)" +msgstr "" + +#: kqalculate.cpp:403 kqalculate.cpp:946 +msgid "x2" +msgstr "" + +#: kqalculate.cpp:404 +msgid "Square" +msgstr "" + +#: kqalculate.cpp:406 +msgid "log" +msgstr "" + +#: kqalculate.cpp:407 +msgid "Base-10 logarithm" +msgstr "" + +#: kqalculate.cpp:409 +msgid "ln" +msgstr "" + +#: kqalculate.cpp:410 +msgid "Natural logarithm" +msgstr "" + +#: kqalculate.cpp:412 +msgid "x!" +msgstr "" + +#: kqalculate.cpp:413 +msgid "Factorial" +msgstr "" + +#: kqalculate.cpp:415 +msgid "cos" +msgstr "" + +#: kqalculate.cpp:416 +msgid "Cosine" +msgstr "" + +#: kqalculate.cpp:418 +msgid "tan" +msgstr "" + +#: kqalculate.cpp:419 +msgid "Tangent" +msgstr "" + +#: kqalculate.cpp:421 +msgid "hyp" +msgstr "" + +#: kqalculate.cpp:422 +msgid "Toggle hyperbolic functions" +msgstr "" + +#: kqalculate.cpp:425 +msgid "inv" +msgstr "" + +#: kqalculate.cpp:426 +msgid "Toggle inverse functions" +msgstr "" + +#: kqalculate.cpp:429 +msgid "sin" +msgstr "" + +#: kqalculate.cpp:430 +msgid "Sine" +msgstr "" + +#: kqalculate.cpp:435 +msgid "Deg" +msgstr "" + +#: kqalculate.cpp:436 +msgid "Angle Unit: Degrees" +msgstr "" + +#: kqalculate.cpp:439 +msgid "Rad" +msgstr "" + +#: kqalculate.cpp:440 +msgid "Angle Unit: Radians" +msgstr "" + +#: kqalculate.cpp:443 +msgid "Gra" +msgstr "" + +#: kqalculate.cpp:444 +msgid "Angle Unit: Gradians" +msgstr "" + +#: kqalculate.cpp:447 kqalculate.cpp:1094 kqalculate.cpp:1152 +#: qalculateplotdialog.cpp:126 +msgid "None" +msgstr "" + +#: kqalculate.cpp:464 +msgid "7" +msgstr "" + +#: kqalculate.cpp:466 +msgid "8" +msgstr "" + +#: kqalculate.cpp:468 +msgid "9" +msgstr "" + +#: kqalculate.cpp:470 +msgid "4" +msgstr "" + +#: kqalculate.cpp:472 +msgid "5" +msgstr "" + +#: kqalculate.cpp:474 +msgid "6" +msgstr "" + +#: kqalculate.cpp:476 +msgid "1" +msgstr "" + +#: kqalculate.cpp:478 +msgid "2" +msgstr "" + +#: kqalculate.cpp:480 +msgid "3" +msgstr "" + +#: kqalculate.cpp:482 +msgid "0" +msgstr "" + +#: kqalculate.cpp:485 +msgid "Decimal point" +msgstr "" + +#: kqalculate.cpp:487 +msgid "EXP" +msgstr "" + +#: kqalculate.cpp:488 +msgid "10^x (Ctrl+Shift+E)" +msgstr "" + +#: kqalculate.cpp:491 +msgid "Del" +msgstr "" + +#: kqalculate.cpp:494 +msgid "AC" +msgstr "" + +#: kqalculate.cpp:498 +msgid "Multiply" +msgstr "" + +#: kqalculate.cpp:501 +msgid "Divide" +msgstr "" + +#: kqalculate.cpp:507 +msgid "Subtract" +msgstr "" + +#: kqalculate.cpp:509 +msgid "Ans" +msgstr "" + +#: kqalculate.cpp:510 +msgid "Previous result" +msgstr "" + +#: kqalculate.cpp:512 kqalculate.cpp:4488 +msgid "Ent" +msgstr "" + +#: kqalculate.cpp:535 +msgid "Index" +msgstr "" + +#: kqalculate.cpp:536 qalculateeditdataobjectdialog.cpp:49 +#: qalculatevariablesdialog.cpp:61 +msgid "Value" +msgstr "" + +#: kqalculate.cpp:555 kqalculate.cpp:5924 +msgid "Up" +msgstr "" + +#: kqalculate.cpp:556 +msgid "Move selected register up" +msgstr "" + +#: kqalculate.cpp:560 kqalculate.cpp:5926 +msgid "Down" +msgstr "" + +#: kqalculate.cpp:561 +msgid "Move selected register down" +msgstr "" + +#: kqalculate.cpp:566 +msgid "Edit value of selected register" +msgstr "" + +#: kqalculate.cpp:571 +msgid "Delete selected register" +msgstr "" + +#: kqalculate.cpp:576 +msgid "Clear the RPN stack" +msgstr "" + +#: kqalculate.cpp:592 +msgid "Keypad" +msgstr "" + +#: kqalculate.cpp:593 +msgid "Show/hide keypad" +msgstr "" + +#: kqalculate.cpp:596 +msgid "History" +msgstr "" + +#: kqalculate.cpp:597 +msgid "Show/hide history" +msgstr "" + +#: kqalculate.cpp:600 +msgid "RPN Stack" +msgstr "" + +#: kqalculate.cpp:601 +msgid "Show/hide RPN stack" +msgstr "" + +#: kqalculate.cpp:716 kqalculate.cpp:2527 +msgid "RPN Register Moved" +msgstr "" + +#: kqalculate.cpp:752 kqalculate.cpp:784 kqalculate.cpp:2138 +#: kqalculate.cpp:2702 kqalculate.cpp:2739 +msgid "approx." +msgstr "" + +#: kqalculate.cpp:894 kqalculate.cpp:4813 +msgid "Load meta mode: %1" +msgstr "" + +#: kqalculate.cpp:966 +msgid "Qalculate! - Scientific Calculator" +msgstr "" + +#: kqalculate.cpp:985 qalculateeditfunctiondialog.cpp:601 +#: qalculateresultdisplay.cpp:62 +msgid "Variable" +msgstr "" + +#: kqalculate.cpp:986 qalculateeditfunctiondialog.cpp:596 +#: qalculateeditmatrixvectordialog.cpp:106 qalculateimportcsvdialog.cpp:52 +#: qalculateinsertmatrixvectordialog.cpp:85 +#: qalculateinsertmatrixvectordialog.cpp:310 +msgid "Matrix" +msgstr "" + +#: kqalculate.cpp:987 qalculateeditfunctiondialog.cpp:595 +#: qalculateeditmatrixvectordialog.cpp:109 +#: qalculateinsertmatrixvectordialog.cpp:88 +#: qalculateinsertmatrixvectordialog.cpp:308 +msgid "Vector" +msgstr "" + +#: kqalculate.cpp:988 +msgid "Unknown Variable" +msgstr "" + +#: kqalculate.cpp:989 qalculateeditdatasetdialog.cpp:70 +#: qalculateeditfunctiondialog.cpp:71 qalculateeditfunctiondialog.cpp:599 +#: qalculateplotdialog.cpp:98 qalculateresultdisplay.cpp:92 +msgid "Function" +msgstr "" + +#: kqalculate.cpp:990 qalculatedatasetsdialog.cpp:64 +msgid "Data Set" +msgstr "" + +#: kqalculate.cpp:991 qalculateconvertunitsdialog.cpp:68 +#: qalculateeditfunctiondialog.cpp:600 qalculateresultdisplay.cpp:67 +#: qalculateunitsdialog.cpp:67 +msgid "Unit" +msgstr "" + +#: kqalculate.cpp:992 +msgid "Import CSV File..." +msgstr "" + +#: kqalculate.cpp:993 +msgid "Export CSV File..." +msgstr "" + +#: kqalculate.cpp:994 +msgid "Store Result..." +msgstr "" + +#: kqalculate.cpp:995 +msgid "Save Result Image..." +msgstr "" + +#: kqalculate.cpp:996 +msgid "Save Definitions" +msgstr "" + +#: kqalculate.cpp:997 +msgid "Update Exchange Rates" +msgstr "" + +#: kqalculate.cpp:998 +msgid "Plot Functions/Data" +msgstr "" + +#: kqalculate.cpp:1000 +msgid "Convert Number Bases" +msgstr "" + +#: kqalculate.cpp:1001 qalculateperiodictabledialog.cpp:40 +msgid "Periodic Table" +msgstr "" + +#: kqalculate.cpp:1008 +msgid "Show/hide main Qalculate! window" +msgstr "" + +#: kqalculate.cpp:1011 +msgid "Configure &Global Shortcuts..." +msgstr "" + +#: kqalculate.cpp:1013 +msgid "Manage Variables" +msgstr "" + +#: kqalculate.cpp:1014 +msgid "Manage Functions" +msgstr "" + +#: kqalculate.cpp:1015 +msgid "Manage Units" +msgstr "" + +#: kqalculate.cpp:1016 +msgid "Manage Data Sets" +msgstr "" + +#: kqalculate.cpp:1017 kqalculate.cpp:1150 +msgid "Factorize" +msgstr "" + +#: kqalculate.cpp:1018 kqalculate.cpp:1148 +msgid "Simplify" +msgstr "" + +#: kqalculate.cpp:1019 +msgid "Set Unknowns..." +msgstr "" + +#: kqalculate.cpp:1020 +msgid "Convert to Unit Expression..." +msgstr "" + +#: kqalculate.cpp:1021 kqalculate.cpp:1084 +msgid "Convert to Base Units" +msgstr "" + +#: kqalculate.cpp:1022 kqalculate.cpp:1086 +msgid "Convert to Best Unit" +msgstr "" + +#: kqalculate.cpp:1023 +msgid "Insert Matrix..." +msgstr "" + +#: kqalculate.cpp:1024 +msgid "Insert Vector..." +msgstr "" + +#: kqalculate.cpp:1025 +msgid "Copy Result" +msgstr "" + +#: kqalculate.cpp:1026 +msgid "Clear History" +msgstr "" + +#: kqalculate.cpp:1027 +msgid "Configure Qalculate!" +msgstr "" + +#: kqalculate.cpp:1043 +msgid "Roman Numerals" +msgstr "" + +#: kqalculate.cpp:1045 +msgid "Select Result and Expression Base..." +msgstr "" + +#: kqalculate.cpp:1052 +msgid "Purely Scientific" +msgstr "" + +#: kqalculate.cpp:1056 +msgid "Indicate Infinite Series" +msgstr "" + +#: kqalculate.cpp:1058 +msgid "Sort Minus Last" +msgstr "" + +#: kqalculate.cpp:1060 +msgid "Negative Exponents" +msgstr "" + +#: kqalculate.cpp:1062 +msgid "Show Ending Zeroes" +msgstr "" + +#: kqalculate.cpp:1064 +msgid "Round Halfway Numbers to Even" +msgstr "" + +#: kqalculate.cpp:1068 +msgid "Decimal (Try Exact)" +msgstr "" + +#: kqalculate.cpp:1072 +msgid "Combined" +msgstr "" + +#: kqalculate.cpp:1074 +msgid "Enable Prefixes" +msgstr "" + +#: kqalculate.cpp:1076 +msgid "Enable Use of All SI Prefixes" +msgstr "" + +#: kqalculate.cpp:1078 +msgid "Enable Denominator Prefixes" +msgstr "" + +#: kqalculate.cpp:1080 +msgid "Place Units Separately" +msgstr "" + +#: kqalculate.cpp:1082 +msgid "No Automatic Conversion" +msgstr "" + +#: kqalculate.cpp:1088 +msgid "Degrees" +msgstr "" + +#: kqalculate.cpp:1090 +msgid "Radians" +msgstr "" + +#: kqalculate.cpp:1092 +msgid "Gradians" +msgstr "" + +#: kqalculate.cpp:1096 +msgid "Abbreviate Names" +msgstr "" + +#: kqalculate.cpp:1098 +msgid "Enable Variables" +msgstr "" + +#: kqalculate.cpp:1100 +msgid "Enable Functions" +msgstr "" + +#: kqalculate.cpp:1102 +msgid "Enable Units" +msgstr "" + +#: kqalculate.cpp:1104 +msgid "Enable Unknowns" +msgstr "" + +#: kqalculate.cpp:1106 +msgid "Calculate Variables" +msgstr "" + +#: kqalculate.cpp:1108 +msgid "Allow Complex Result" +msgstr "" + +#: kqalculate.cpp:1110 +msgid "Allow Infinite Result" +msgstr "" + +#: kqalculate.cpp:1112 +msgid "Try Exact" +msgstr "" + +#: kqalculate.cpp:1114 +msgid "Always Exact" +msgstr "" + +#: kqalculate.cpp:1116 qalculateeditdataobjectdialog.cpp:70 +msgid "Approximate" +msgstr "" + +#: kqalculate.cpp:1118 kqalculate.cpp:1132 +#: qalculateeditunknownvariabledialog.cpp:65 +#: qalculateeditunknownvariabledialog.cpp:78 +#: qalculateperiodictabledialog.cpp:235 +msgid "Unknown" +msgstr "" + +#: kqalculate.cpp:1120 qalculateeditunknownvariabledialog.cpp:66 +msgid "Not Matrix" +msgstr "" + +#: kqalculate.cpp:1122 qalculateeditdatasetdialog.cpp:468 +#: qalculateeditfunctiondialog.cpp:590 +#: qalculateeditunknownvariabledialog.cpp:67 +msgid "Number" +msgstr "" + +#: kqalculate.cpp:1124 +msgid "Complex" +msgstr "" + +#: kqalculate.cpp:1126 +msgid "Real" +msgstr "" + +#: kqalculate.cpp:1128 +msgid "Rational" +msgstr "" + +#: kqalculate.cpp:1130 qalculateeditfunctiondialog.cpp:591 +#: qalculateeditunknownvariabledialog.cpp:71 +msgid "Integer" +msgstr "" + +#: kqalculate.cpp:1134 qalculateeditunknownvariabledialog.cpp:83 +msgid "Non-Zero" +msgstr "" + +#: kqalculate.cpp:1136 qalculateeditunknownvariabledialog.cpp:79 +msgid "Positive" +msgstr "" + +#: kqalculate.cpp:1138 qalculateeditunknownvariabledialog.cpp:80 +msgid "Non-Negative" +msgstr "" + +#: kqalculate.cpp:1140 qalculateeditunknownvariabledialog.cpp:81 +msgid "Negative" +msgstr "" + +#: kqalculate.cpp:1142 qalculateeditunknownvariabledialog.cpp:82 +msgid "Non-Positive" +msgstr "" + +#: kqalculate.cpp:1144 +msgid "Non-Zero Denominators" +msgstr "" + +#: kqalculate.cpp:1146 +msgid "Warn About Denominators Assumed Non-Zero" +msgstr "" + +#: kqalculate.cpp:1154 +msgid "Read Precision" +msgstr "" + +#: kqalculate.cpp:1156 +msgid "Limit Implicit Multiplication" +msgstr "" + +#: kqalculate.cpp:1158 +msgid "RPN Mode" +msgstr "" + +#: kqalculate.cpp:1160 +msgid "RPN Syntax" +msgstr "" + +#: kqalculate.cpp:1162 qalculateprecisiondialog.cpp:31 +msgid "Precision" +msgstr "" + +#: kqalculate.cpp:1163 qalculatedecimalsdialog.cpp:27 +msgid "Decimals" +msgstr "" + +#: kqalculate.cpp:1164 +msgid "Save Mode..." +msgstr "" + +#: kqalculate.cpp:1165 +msgid "Delete Mode..." +msgstr "" + +#: kqalculate.cpp:1167 +msgid "Save Default Mode" +msgstr "" + +#: kqalculate.cpp:1168 +msgid "Clear Stack" +msgstr "" + +#: kqalculate.cpp:1172 +msgid "Exp RPN Operation" +msgstr "" + +#: kqalculate.cpp:1860 +msgid "and" +msgstr "" + +#: kqalculate.cpp:1865 +msgid "or" +msgstr "" + +#: kqalculate.cpp:2122 +msgid "undefined" +msgstr "" + +#: kqalculate.cpp:2164 +msgid "EXACT" +msgstr "" + +#: kqalculate.cpp:2167 +msgid "APPROX" +msgstr "" + +#: kqalculate.cpp:2171 +msgid "RPN" +msgstr "" + +#: kqalculate.cpp:2179 +msgid "BIN" +msgstr "" + +#: kqalculate.cpp:2184 +msgid "OCT" +msgstr "" + +#: kqalculate.cpp:2189 +msgid "HEX" +msgstr "" + +#: kqalculate.cpp:2194 +msgid "ROMAN" +msgstr "" + +#: kqalculate.cpp:2206 +msgid "DEG" +msgstr "" + +#: kqalculate.cpp:2211 +msgid "RAD" +msgstr "" + +#: kqalculate.cpp:2216 +msgid "GRA" +msgstr "" + +#: kqalculate.cpp:2223 +msgid "PREC" +msgstr "" + +#: kqalculate.cpp:2228 +msgid "FUNC" +msgstr "" + +#: kqalculate.cpp:2234 +msgid "UNIT" +msgstr "" + +#: kqalculate.cpp:2240 +msgid "VAR" +msgstr "" + +#: kqalculate.cpp:2246 +msgid "INF" +msgstr "" + +#: kqalculate.cpp:2252 +msgid "CPLX" +msgstr "" + +#: kqalculate.cpp:2333 kqalculate.cpp:2351 kqalculate.cpp:2581 +msgid "aborted" +msgstr "" + +#: kqalculate.cpp:2352 +msgid "calculation was aborted" +msgstr "" + +#: kqalculate.cpp:2588 +msgid "result processing was aborted" +msgstr "" + +#: kqalculate.cpp:2636 +msgid "Processing..." +msgstr "" + +#: kqalculate.cpp:2640 kqalculate.cpp:2885 kqalculate.cpp:3145 +msgid "Abort" +msgstr "" + +#: kqalculate.cpp:2873 +msgid "Factorizing..." +msgstr "" + +#: kqalculate.cpp:2877 +msgid "Simplifying..." +msgstr "" + +#: kqalculate.cpp:3141 +msgid "Calculating..." +msgstr "" + +#: kqalculate.cpp:3191 +msgid "RPN Operation" +msgstr "" + +#: kqalculate.cpp:3259 +msgid "Errors" +msgstr "" + +#: kqalculate.cpp:3260 +msgid "Warnings" +msgstr "" + +#: kqalculate.cpp:3270 +msgid "Couldn't write definitions" +msgstr "" + +#: kqalculate.cpp:3538 +msgid "Prefixes" +msgstr "" + +#: kqalculate.cpp:3665 +msgid "No Prefix" +msgstr "" + +#: kqalculate.cpp:3816 qalculatevariablesdialog.cpp:191 +#: qalculatevariablesdialog.cpp:337 +msgid "Variable does not exist anymore." +msgstr "" + +#: kqalculate.cpp:3832 qalculateconvertunitsdialog.cpp:153 +#: qalculateunitsdialog.cpp:223 qalculateunitsdialog.cpp:337 +msgid "Unit does not exist anymore." +msgstr "" + +#: kqalculate.cpp:3905 +msgid "Failed to download exchange rates from ECB." +msgstr "" + +#: kqalculate.cpp:4752 +msgid "Save Mode" +msgstr "" + +#: kqalculate.cpp:4755 +msgid "Mode name:" +msgstr "" + +#: kqalculate.cpp:4765 +msgid "Shortcut:" +msgstr "" + +#: kqalculate.cpp:4792 +msgid "Empty mode name." +msgstr "" + +#: kqalculate.cpp:4795 +msgid "Preset mode cannot be overwritten." +msgstr "" + +#: kqalculate.cpp:4827 +msgid "Delete Mode" +msgstr "" + +#: kqalculate.cpp:4827 +msgid "Mode:" +msgstr "" + +#: kqalculate.cpp:5001 +msgid "log10 function not found." +msgstr "" + +#: kqalculate.cpp:5545 main.cpp:156 main.cpp:159 main.cpp:160 main.cpp:161 +#: main.cpp:162 +msgid "Temporary" +msgstr "" + +#: kqalculate.cpp:5567 kqalculate.cpp:5594 qalculatefunctionsdialog.cpp:191 +#: qalculatefunctionsdialog.cpp:300 +msgid "Function does not exist anymore." +msgstr "" + +#: kqalculate.cpp:5697 kqalculate.cpp:5733 +msgid "My Variables" +msgstr "" + +#: kqalculate.cpp:5709 qalculateimportcsvdialog.cpp:56 +msgid "Vectors" +msgstr "" + +#: kqalculate.cpp:5721 +msgid "Matrices" +msgstr "" + +#: kqalculate.cpp:5762 qalculateplotdialog.cpp:726 +msgid "Save Image" +msgstr "" + +#: kqalculate.cpp:5767 qalculateplotdialog.cpp:731 +msgid "" +"A file named \"%1\" already exists. Are you sure you want to overwrite it?" +msgstr "" + +#: kqalculate.cpp:5767 qalculateplotdialog.cpp:731 +msgid "Overwrite File?" +msgstr "" + +#: kqalculate.cpp:5767 qalculateplotdialog.cpp:731 +msgid "&Overwrite" +msgstr "" + +#: kqalculate.cpp:5801 +msgid "Failed to save image." +msgstr "" + +#: kqalculate.cpp:6027 +msgid "No unknowns in result." +msgstr "" + +#: kqalculate.cpp:6030 +msgid "Set Unknowns" +msgstr "" + +#: kqalculate.cpp:6194 +msgid "Too many arguments for %1()." +msgstr "" + +#: kqalculate.cpp:6220 qalculatedatasetsdialog.cpp:342 +#: qalculatefunctionsdialog.cpp:343 qalculateresultdisplay.cpp:120 +msgid "argument" +msgstr "" + +#: kqalculate.cpp:6442 kqalculate.cpp:6446 +msgid "Edit Expression" +msgstr "" + +#: kqalculate.cpp:6451 +msgid "Edit Result" +msgstr "" + +#: kqalculate.cpp:6454 +msgid "Insert Result Variable" +msgstr "" + +#: main.cpp:45 +msgid "A powerful and easy to use desktop calculator" +msgstr "" + +#: main.cpp:51 +msgid "Calculate X11-clipboard content (selected text)" +msgstr "" + +#: main.cpp:52 +msgid "Initial expression to calculate" +msgstr "" + +#: main.cpp:134 +msgid "Enter a mathematical expression above.
Ex. 5 + 2 / 3" +msgstr "" + +#: main.cpp:143 +msgid "" +"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" +"\n" +"Do you want to fetch exchange rates now from the Internet?" +msgstr "" + +#: main.cpp:143 +msgid "Update exchange rates?" +msgstr "" + +#: main.cpp:155 +msgid "ans" +msgstr "" + +#: main.cpp:156 +msgid "Last Answer" +msgstr "" + +#: main.cpp:157 +msgid "answer" +msgstr "" + +#: main.cpp:159 +msgid "Answer 2" +msgstr "" + +#: main.cpp:160 +msgid "Answer 3" +msgstr "" + +#: main.cpp:161 +msgid "Answer 4" +msgstr "" + +#: main.cpp:162 +msgid "Answer 5" +msgstr "" + +#: main.cpp:166 +msgid "Failed to load global definitions!" +msgstr "" + +#: main.cpp:290 +msgid "Qalculate!" +msgstr "" + +#: preferences.cpp:208 +msgid "Preset" +msgstr "" + +#: preferences.cpp:669 +#, c-format +msgid "" +"Couldn't write preferences to\n" +"%s" +msgstr "" + +#: qalculateconvertnumberbasesdialog.cpp:31 qalculatesetbasedialog.cpp:29 +msgid "Number Bases" +msgstr "" + +#: qalculateconvertnumberbasesdialog.cpp:37 +msgid "Decimal:" +msgstr "" + +#: qalculateconvertnumberbasesdialog.cpp:41 +msgid "Binary:" +msgstr "" + +#: qalculateconvertnumberbasesdialog.cpp:45 +msgid "Octal:" +msgstr "" + +#: qalculateconvertnumberbasesdialog.cpp:49 +msgid "Hexadecimal:" +msgstr "" + +#: qalculateconvertunitsdialog.cpp:44 +msgid "Selector" +msgstr "" + +#: qalculateconvertunitsdialog.cpp:50 qalculateeditdatasetdialog.cpp:482 +msgid "Unit expression:" +msgstr "" + +#: qalculateconvertunitsdialog.cpp:63 qalculatefunctionsdialog.cpp:55 +#: qalculateunitsdialog.cpp:63 qalculatevariablesdialog.cpp:57 +msgid "Category" +msgstr "" + +#: qalculateconvertunitsdialog.cpp:85 qalculateconvertunitsdialog.cpp:86 +#: qalculateconvertunitsdialog.cpp:141 qalculateconvertunitsdialog.cpp:180 +#: qalculatefunctionsdialog.cpp:118 qalculatefunctionsdialog.cpp:119 +#: qalculatefunctionsdialog.cpp:183 qalculatefunctionsdialog.cpp:505 +#: qalculateunitsdialog.cpp:150 qalculateunitsdialog.cpp:151 +#: qalculateunitsdialog.cpp:215 qalculateunitsdialog.cpp:416 +#: qalculatevariablesdialog.cpp:116 qalculatevariablesdialog.cpp:117 +#: qalculatevariablesdialog.cpp:183 qalculatevariablesdialog.cpp:462 +msgid "All" +msgstr "" + +#: qalculateconvertunitsdialog.cpp:132 qalculateconvertunitsdialog.cpp:133 +#: qalculateconvertunitsdialog.cpp:134 qalculateconvertunitsdialog.cpp:182 +#: qalculatefunctionsdialog.cpp:165 qalculatefunctionsdialog.cpp:166 +#: qalculatefunctionsdialog.cpp:167 qalculatefunctionsdialog.cpp:236 +#: qalculatefunctionsdialog.cpp:262 qalculatefunctionsdialog.cpp:285 +#: qalculatefunctionsdialog.cpp:507 qalculateunitsdialog.cpp:197 +#: qalculateunitsdialog.cpp:198 qalculateunitsdialog.cpp:199 +#: qalculateunitsdialog.cpp:273 qalculateunitsdialog.cpp:299 +#: qalculateunitsdialog.cpp:322 qalculateunitsdialog.cpp:418 +#: qalculatevariablesdialog.cpp:165 qalculatevariablesdialog.cpp:166 +#: qalculatevariablesdialog.cpp:167 qalculatevariablesdialog.cpp:258 +#: qalculatevariablesdialog.cpp:284 qalculatevariablesdialog.cpp:322 +#: qalculatevariablesdialog.cpp:464 +msgid "Uncategorized" +msgstr "" + +#: qalculatedatasetsdialog.cpp:46 qalculateeditdatasetdialog.cpp:232 +msgid "Data Sets" +msgstr "" + +#: qalculatedatasetsdialog.cpp:61 +msgid "Data Sets:" +msgstr "" + +#: qalculatedatasetsdialog.cpp:68 qalculatedatasetsdialog.cpp:91 +#: qalculateeditdatasetdialog.cpp:107 qalculateeditdatasetdialog.cpp:629 +#: qalculateeditfunctiondialog.cpp:133 qalculateeditfunctiondialog.cpp:492 +#: qalculateeditnamesdialog.cpp:64 qalculatefunctionsdialog.cpp:67 +#: qalculateunitsdialog.cpp:91 qalculatevariablesdialog.cpp:66 +msgid "New" +msgstr "" + +#: qalculatedatasetsdialog.cpp:77 qalculateeditdatasetdialog.cpp:79 +#: qalculateeditdatasetdialog.cpp:456 qalculateeditfunctiondialog.cpp:98 +msgid "Description:" +msgstr "" + +#: qalculatedatasetsdialog.cpp:84 +msgid "Objects:" +msgstr "" + +#: qalculatedatasetsdialog.cpp:87 qalculateeditdatasetdialog.cpp:236 +#: qalculateeditfunctiondialog.cpp:598 +msgid "Object" +msgstr "" + +#: qalculatedatasetsdialog.cpp:100 +msgid "Attributes:" +msgstr "" + +#: qalculatedatasetsdialog.cpp:157 qalculatedatasetsdialog.cpp:218 +msgid "Data set does not exist anymore." +msgstr "" + +#: qalculatedatasetsdialog.cpp:300 qalculateeditdatasetdialog.cpp:195 +#: qalculatefunctionsdialog.cpp:456 +msgid "key" +msgstr "" + +#: qalculatedatasetsdialog.cpp:316 +msgid "Data Retrieval Function" +msgstr "" + +#: qalculatedecimalsdialog.cpp:31 +msgid "Max decimals:" +msgstr "" + +#: qalculatedecimalsdialog.cpp:39 +msgid "Min decimals:" +msgstr "" + +#: qalculateeditdataobjectdialog.cpp:30 qalculateeditdataobjectdialog.cpp:40 +msgid "Edit Object" +msgstr "" + +#: qalculateeditdataobjectdialog.cpp:42 +msgid "New Object" +msgstr "" + +#: qalculateeditdataobjectdialog.cpp:48 qalculateeditdatasetdialog.cpp:242 +msgid "Property" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 116 +#: qalculateeditdataobjectdialog.cpp:51 rc.cpp:39 +#, no-c-format +msgid "Approximation" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:53 qalculateeditdatasetdialog.cpp:307 +msgid "Edit Data Set" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:68 qalculateeditfunctiondialog.cpp:70 +#: qalculatepreferencesdialog.cpp:157 +msgid "General" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:73 qalculateplotdialog.cpp:86 +#: qalculateplotdialog.cpp:189 +msgid "Title:" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:76 +msgid "Data file:" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:87 +msgid "Copyright:" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:97 +msgid "Properties:" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:99 qalculateplotdialog.cpp:153 +msgid "Title" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:100 qalculateeditdatasetdialog.cpp:620 +#: qalculateeditfunctiondialog.cpp:124 qalculateeditnamesdialog.cpp:41 +#: qalculateeditunitdialog.cpp:50 +msgid "Name" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:101 qalculateeditfunctiondialog.cpp:125 +#: qalculateeditunitdialog.cpp:75 qalculateeditunknownvariabledialog.cpp:60 +msgid "Type" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:115 qalculateeditdatasetdialog.cpp:442 +#: qalculateeditfunctiondialog.cpp:74 qalculateeditfunctiondialog.cpp:583 +#: qalculateeditmatrixvectordialog.cpp:78 qalculateeditunitdialog.cpp:55 +#: qalculateeditunknownvariabledialog.cpp:47 +#: qalculateeditvariabledialog.cpp:49 qalculateimportcsvdialog.cpp:60 +msgid "Name:" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:124 qalculateeditdatasetdialog.cpp:451 +#: qalculateeditfunctiondialog.cpp:83 qalculateeditmatrixvectordialog.cpp:87 +#: qalculateeditunitdialog.cpp:64 qalculateeditunknownvariabledialog.cpp:56 +#: qalculateeditvariabledialog.cpp:60 +msgid "Names Details" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:126 +msgid "Object argument name:" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:129 +msgid "Property argument name:" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:132 +msgid "Default property:" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:173 +msgid "text" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:178 qalculateeditdatasetdialog.cpp:186 +msgid "approximate" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:181 qalculateexpressionedit.cpp:712 +#: qalculatevariablesdialog.cpp:428 +msgid "number" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:189 +msgid "expression" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:213 qalculateeditdatasetdialog.cpp:499 +#: qalculateeditfunctiondialog.cpp:190 qalculateeditmatrixvectordialog.cpp:185 +#: qalculateeditunitdialog.cpp:146 qalculateeditunknownvariabledialog.cpp:132 +#: qalculateeditvariabledialog.cpp:102 +msgid "Empty name field" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:217 qalculateeditfunctiondialog.cpp:201 +msgid "" +"A function with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:309 +msgid "Edit Data Set (global)" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:311 +msgid "New Data Set" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:322 +msgid "info" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:435 qalculateeditdatasetdialog.cpp:548 +msgid "Edit Property" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:453 qalculateeditfunctiondialog.cpp:90 +#: qalculateeditmatrixvectordialog.cpp:93 qalculateeditunitdialog.cpp:66 +#: qalculateeditunknownvariabledialog.cpp:90 +#: qalculateeditvariabledialog.cpp:80 qalculateimportcsvdialog.cpp:63 +msgid "Descriptive name:" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:464 +msgid "Value type:" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:467 qalculateeditfunctiondialog.cpp:593 +msgid "Text" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:469 qalculateeditfunctiondialog.cpp:482 +#: qalculateplotdialog.cpp:154 +msgid "Expression" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:474 +msgid "Use as key" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:476 +msgid "Approximate value" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:478 +msgid "Case sensitive value" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:480 +msgid "Value uses brackets" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:550 +msgid "New Property" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:615 qalculateeditnamesdialog.cpp:34 +msgid "Edit Names" +msgstr "" + +#: qalculateeditdatasetdialog.cpp:621 qalculateeditfunctiondialog.cpp:481 +#: qalculateeditnamesdialog.cpp:46 +msgid "Reference" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:55 qalculateeditfunctiondialog.cpp:286 +msgid "Edit Function" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:85 qalculateeditmatrixvectordialog.cpp:89 +#: qalculateeditunitdialog.cpp:87 qalculateeditunknownvariabledialog.cpp:85 +#: qalculateeditvariabledialog.cpp:74 qalculateimportcsvdialog.cpp:66 +msgid "Category:" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:96 +msgid "Hide function" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:106 qalculateplotdialog.cpp:89 +msgid "Expression:" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:115 +msgid "Condition:" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:120 qalculateeditfunctiondialog.cpp:476 +msgid "Sub-Functions" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:122 +msgid "Arguments:" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:197 +msgid "Empty expression field" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:288 +msgid "Edit Function (global)" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:290 +msgid "New Function" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:483 +msgid "Precalculate" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:579 qalculateeditfunctiondialog.cpp:675 +msgid "Edit Argument" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:586 +msgid "Type:" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:589 +msgid "Free" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:592 +msgid "Symbol" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:594 qalculateinsertfunctiondialog.cpp:353 +msgid "Date" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:597 +msgid "Boolean" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:603 +msgid "Angle" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:605 +msgid "Enable rules and type test" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:607 +msgid "Custom condition:" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:611 +msgid "Allow matrix" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:613 +msgid "Forbid zero" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:615 +msgid "Allow complex" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:617 qalculateplotdialog.cpp:164 +msgid "Min:" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:624 qalculateeditfunctiondialog.cpp:633 +msgid "Include equals" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:626 qalculateplotdialog.cpp:167 +msgid "Max:" +msgstr "" + +#: qalculateeditfunctiondialog.cpp:677 +msgid "New Argument" +msgstr "" + +#: qalculateeditmatrixvectordialog.cpp:71 +#: qalculateeditunknownvariabledialog.cpp:40 +#: qalculateeditvariabledialog.cpp:41 qalculateeditvariabledialog.cpp:180 +#: qalculateinsertmatrixvectordialog.cpp:71 +msgid "Edit Variable" +msgstr "" + +#: qalculateeditmatrixvectordialog.cpp:96 +#: qalculateinsertmatrixvectordialog.cpp:75 +msgid "Rows:" +msgstr "" + +#: qalculateeditmatrixvectordialog.cpp:99 +#: qalculateinsertmatrixvectordialog.cpp:78 +msgid "Columns:" +msgstr "" + +#: qalculateeditmatrixvectordialog.cpp:112 +#: qalculateeditmatrixvectordialog.cpp:133 +#: qalculateeditmatrixvectordialog.cpp:295 +#: qalculateinsertmatrixvectordialog.cpp:91 +#: qalculateinsertmatrixvectordialog.cpp:115 +#: qalculateinsertmatrixvectordialog.cpp:275 +msgid "Elements:" +msgstr "" + +#: qalculateeditmatrixvectordialog.cpp:146 +#: qalculateeditmatrixvectordialog.cpp:292 +#: qalculateinsertmatrixvectordialog.cpp:128 +#: qalculateinsertmatrixvectordialog.cpp:272 +msgid "Elements (in horizontal order):" +msgstr "" + +#: qalculateeditmatrixvectordialog.cpp:189 +#: qalculateeditunknownvariabledialog.cpp:136 +#: qalculateeditvariabledialog.cpp:114 +msgid "" +"An unit or variable with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" + +#: qalculateeditmatrixvectordialog.cpp:301 +msgid "Edit Vector" +msgstr "" + +#: qalculateeditmatrixvectordialog.cpp:303 +msgid "Edit Vector (global)" +msgstr "" + +#: qalculateeditmatrixvectordialog.cpp:305 +msgid "New Vector" +msgstr "" + +#: qalculateeditmatrixvectordialog.cpp:310 +msgid "Edit Matrix" +msgstr "" + +#: qalculateeditmatrixvectordialog.cpp:312 +msgid "Edit Matrix (global)" +msgstr "" + +#: qalculateeditmatrixvectordialog.cpp:314 +msgid "New Matrix" +msgstr "" + +#: qalculateeditnamesdialog.cpp:42 +msgid "Abbreviation" +msgstr "" + +#: qalculateeditnamesdialog.cpp:44 +msgid "Plural" +msgstr "" + +#: qalculateeditnamesdialog.cpp:48 +msgid "Avoid Input" +msgstr "" + +#: qalculateeditnamesdialog.cpp:50 +msgid "Unicode" +msgstr "" + +#: qalculateeditnamesdialog.cpp:52 +msgid "Suffix" +msgstr "" + +#: qalculateeditnamesdialog.cpp:54 +msgid "Case Sensitive" +msgstr "" + +#: qalculateeditunitdialog.cpp:43 qalculateeditunitdialog.cpp:287 +msgid "Edit Unit" +msgstr "" + +#: qalculateeditunitdialog.cpp:72 +msgid "Hide unit" +msgstr "" + +#: qalculateeditunitdialog.cpp:80 +msgid "Class:" +msgstr "" + +#: qalculateeditunitdialog.cpp:83 +msgid "Base Unit" +msgstr "" + +#: qalculateeditunitdialog.cpp:84 +msgid "Alias" +msgstr "" + +#: qalculateeditunitdialog.cpp:85 +msgid "Composite Unit" +msgstr "" + +#: qalculateeditunitdialog.cpp:92 +msgid "System:" +msgstr "" + +#: qalculateeditunitdialog.cpp:95 +msgid "SI" +msgstr "" + +#: qalculateeditunitdialog.cpp:96 +msgid "CGS" +msgstr "" + +#: qalculateeditunitdialog.cpp:97 +msgid "Imperial" +msgstr "" + +#: qalculateeditunitdialog.cpp:98 +msgid "US Survey" +msgstr "" + +#: qalculateeditunitdialog.cpp:102 +msgid "Relation" +msgstr "" + +#: qalculateeditunitdialog.cpp:107 +msgid "Base unit:" +msgstr "" + +#: qalculateeditunitdialog.cpp:110 +msgid "Exponent:" +msgstr "" + +#: qalculateeditunitdialog.cpp:114 +msgid "Relation:" +msgstr "" + +#: qalculateeditunitdialog.cpp:121 +msgid "Relation is exact" +msgstr "" + +#: qalculateeditunitdialog.cpp:123 +msgid "Inverse relation:" +msgstr "" + +#: qalculateeditunitdialog.cpp:150 +msgid "" +"A variable or unit with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" + +#: qalculateeditunitdialog.cpp:175 qalculateeditunitdialog.cpp:219 +msgid "Base unit does not exist" +msgstr "" + +#: qalculateeditunitdialog.cpp:289 +msgid "Edit Unit (global)" +msgstr "" + +#: qalculateeditunitdialog.cpp:291 +msgid "New Unit" +msgstr "" + +#: qalculateeditunknownvariabledialog.cpp:58 +msgid "Custom assumptions:" +msgstr "" + +#: qalculateeditunknownvariabledialog.cpp:68 +msgid "Complex Number" +msgstr "" + +#: qalculateeditunknownvariabledialog.cpp:69 +msgid "Real Number" +msgstr "" + +#: qalculateeditunknownvariabledialog.cpp:70 +msgid "Rational Number" +msgstr "" + +#: qalculateeditunknownvariabledialog.cpp:73 +msgid "Sign" +msgstr "" + +#: qalculateeditunknownvariabledialog.cpp:199 +msgid "Edit Unknown Variable" +msgstr "" + +#: qalculateeditunknownvariabledialog.cpp:201 +msgid "Edit Unknown Variable (global)" +msgstr "" + +#: qalculateeditunknownvariabledialog.cpp:203 +msgid "New Unknown Variable" +msgstr "" + +#: qalculateeditvariabledialog.cpp:63 qalculateinsertfunctiondialog.cpp:91 +msgid "Value:" +msgstr "" + +#: qalculateeditvariabledialog.cpp:71 +msgid "Value is exact" +msgstr "" + +#: qalculateeditvariabledialog.cpp:110 +msgid "Empty value field" +msgstr "" + +#: qalculateeditvariabledialog.cpp:182 +msgid "Edit Variable (global)" +msgstr "" + +#: qalculateeditvariabledialog.cpp:185 +msgid "New Variable" +msgstr "" + +#: qalculateexportcsvdialog.cpp:37 qalculateexportcsvdialog.cpp:54 +msgid "Export CSV File" +msgstr "" + +#: qalculateexportcsvdialog.cpp:42 +msgid "Current result" +msgstr "" + +#: qalculateexportcsvdialog.cpp:46 +msgid "Matrix/vector variable" +msgstr "" + +#: qalculateexportcsvdialog.cpp:51 qalculateimportcsvdialog.cpp:43 +msgid "File:" +msgstr "" + +#: qalculateexportcsvdialog.cpp:56 qalculateimportcsvdialog.cpp:80 +msgid "Delimiter:" +msgstr "" + +#: qalculateexportcsvdialog.cpp:59 qalculateimportcsvdialog.cpp:83 +msgid "Comma" +msgstr "" + +#: qalculateexportcsvdialog.cpp:60 qalculateimportcsvdialog.cpp:84 +msgid "Tabulator" +msgstr "" + +#: qalculateexportcsvdialog.cpp:61 qalculateimportcsvdialog.cpp:85 +msgid "Semicolon" +msgstr "" + +#: qalculateexportcsvdialog.cpp:62 qalculateimportcsvdialog.cpp:86 +msgid "Space" +msgstr "" + +#: qalculateexportcsvdialog.cpp:63 qalculateimportcsvdialog.cpp:87 +msgid "Other" +msgstr "" + +#: qalculateexportcsvdialog.cpp:93 qalculateimportcsvdialog.cpp:116 +msgid "No file name entered." +msgstr "" + +#: qalculateexportcsvdialog.cpp:122 qalculateimportcsvdialog.cpp:145 +msgid "No delimiter selected." +msgstr "" + +#: qalculateexportcsvdialog.cpp:135 +msgid "No variable name entered." +msgstr "" + +#: qalculateexportcsvdialog.cpp:147 +msgid "No known variable with entered name found." +msgstr "" + +#: qalculateexportcsvdialog.cpp:154 +#, c-format +msgid "" +"Could not export to file \n" +"%s" +msgstr "" + +#: qalculateexpressionedit.cpp:146 +msgid "Disable Completion" +msgstr "" + +#: qalculateexpressionedit.cpp:147 +msgid "Enable Completion" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 154 +#: qalculateexpressionedit.cpp:161 qalculateresultdisplay.cpp:333 rc.cpp:48 +#, no-c-format +msgid "Meta Modes" +msgstr "" + +#: qalculateexpressionedit.cpp:655 qalculatevariablesdialog.cpp:366 +msgid "a previous result" +msgstr "" + +#: qalculateexpressionedit.cpp:661 qalculatevariablesdialog.cpp:376 +msgid "matrix" +msgstr "" + +#: qalculateexpressionedit.cpp:663 qalculatevariablesdialog.cpp:378 +msgid "vector" +msgstr "" + +#: qalculateexpressionedit.cpp:672 qalculatevariablesdialog.cpp:387 +msgid "positive" +msgstr "" + +#: qalculateexpressionedit.cpp:676 qalculatevariablesdialog.cpp:391 +msgid "non-positive" +msgstr "" + +#: qalculateexpressionedit.cpp:680 qalculatevariablesdialog.cpp:395 +msgid "negative" +msgstr "" + +#: qalculateexpressionedit.cpp:684 qalculatevariablesdialog.cpp:399 +msgid "non-negative" +msgstr "" + +#: qalculateexpressionedit.cpp:688 qalculatevariablesdialog.cpp:403 +msgid "non-zero" +msgstr "" + +#: qalculateexpressionedit.cpp:696 qalculatevariablesdialog.cpp:412 +msgid "integer" +msgstr "" + +#: qalculateexpressionedit.cpp:700 qalculatevariablesdialog.cpp:416 +msgid "rational" +msgstr "" + +#: qalculateexpressionedit.cpp:704 qalculatevariablesdialog.cpp:420 +msgid "real" +msgstr "" + +#: qalculateexpressionedit.cpp:708 qalculatevariablesdialog.cpp:424 +msgid "complex" +msgstr "" + +#: qalculateexpressionedit.cpp:716 qalculatevariablesdialog.cpp:432 +msgid "(not matrix)" +msgstr "" + +#: qalculateexpressionedit.cpp:721 qalculatevariablesdialog.cpp:438 +msgid "unknown" +msgstr "" + +#: qalculateexpressionedit.cpp:723 qalculatevariablesdialog.cpp:440 +msgid "default assumptions" +msgstr "" + +#: qalculatefunctionsdialog.cpp:47 +msgid "Functions" +msgstr "" + +#: qalculatefunctionsdialog.cpp:59 +msgid "Function Name" +msgstr "" + +#: qalculatefunctionsdialog.cpp:75 qalculatefunctionsdialog.cpp:313 +#: qalculateunitsdialog.cpp:99 qalculateunitsdialog.cpp:352 +#: qalculatevariablesdialog.cpp:74 qalculatevariablesdialog.cpp:349 +msgid "Deactivate" +msgstr "" + +#: qalculatefunctionsdialog.cpp:174 qalculatefunctionsdialog.cpp:175 +#: qalculatefunctionsdialog.cpp:176 qalculatefunctionsdialog.cpp:234 +#: qalculatefunctionsdialog.cpp:260 qalculatefunctionsdialog.cpp:283 +#: qalculatefunctionsdialog.cpp:509 qalculateunitsdialog.cpp:206 +#: qalculateunitsdialog.cpp:207 qalculateunitsdialog.cpp:208 +#: qalculateunitsdialog.cpp:271 qalculateunitsdialog.cpp:297 +#: qalculateunitsdialog.cpp:320 qalculateunitsdialog.cpp:420 +#: qalculatevariablesdialog.cpp:174 qalculatevariablesdialog.cpp:175 +#: qalculatevariablesdialog.cpp:176 qalculatevariablesdialog.cpp:256 +#: qalculatevariablesdialog.cpp:282 qalculatevariablesdialog.cpp:320 +#: qalculatevariablesdialog.cpp:466 +msgid "Inactive" +msgstr "" + +#: qalculatefunctionsdialog.cpp:315 qalculateunitsdialog.cpp:354 +#: qalculatevariablesdialog.cpp:351 +msgid "Activate" +msgstr "" + +#: qalculatefunctionsdialog.cpp:367 qalculateresultdisplay.cpp:148 +#, c-format +msgid "" +"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." +msgstr "" + +#: qalculatefunctionsdialog.cpp:391 +msgid "Arguments" +msgstr "" + +#: qalculatefunctionsdialog.cpp:412 qalculateinsertfunctiondialog.cpp:194 +#: qalculateinsertfunctiondialog.cpp:227 +msgid "optional" +msgstr "" + +#: qalculatefunctionsdialog.cpp:416 +msgid "default: " +msgstr "" + +#: qalculatefunctionsdialog.cpp:426 +msgid "Requirement" +msgstr "" + +#: qalculateimportcsvdialog.cpp:39 qalculateimportcsvdialog.cpp:46 +msgid "Import CSV File" +msgstr "" + +#: qalculateimportcsvdialog.cpp:48 +msgid "Import as:" +msgstr "" + +#: qalculateimportcsvdialog.cpp:71 +msgid "First row:" +msgstr "" + +#: qalculateimportcsvdialog.cpp:77 +msgid "Includes headings" +msgstr "" + +#: qalculateimportcsvdialog.cpp:149 +msgid "An error occured when importing the CSV file." +msgstr "" + +#: qalculateinsertfunctiondialog.cpp:50 qalculateinsertfunctiondialog.cpp:57 +msgid "Execute" +msgstr "" + +#: qalculateinsertfunctiondialog.cpp:93 +msgid "Argument" +msgstr "" + +#: qalculateinsertfunctiondialog.cpp:152 +msgid "True" +msgstr "" + +#: qalculateinsertfunctiondialog.cpp:153 +msgid "False" +msgstr "" + +#: qalculateinsertfunctiondialog.cpp:184 +msgid "Info" +msgstr "" + +#: qalculateinsertmatrixvectordialog.cpp:71 +msgid "Insert Selection" +msgstr "" + +#: qalculateinsertmatrixvectordialog.cpp:293 +msgid "Vector Result" +msgstr "" + +#: qalculateinsertmatrixvectordialog.cpp:295 +msgid "Matrix Result" +msgstr "" + +#: qalculateperiodictabledialog.cpp:195 +msgid "Element Data" +msgstr "" + +#: qalculateperiodictabledialog.cpp:221 +msgid "Classification" +msgstr "" + +#: qalculateperiodictabledialog.cpp:224 +msgid "Alkali Metal" +msgstr "" + +#: qalculateperiodictabledialog.cpp:225 +msgid "Alkaline-Earth Metal" +msgstr "" + +#: qalculateperiodictabledialog.cpp:226 +msgid "Lanthanide" +msgstr "" + +#: qalculateperiodictabledialog.cpp:227 +msgid "Actinide" +msgstr "" + +#: qalculateperiodictabledialog.cpp:228 +msgid "Transition Metal" +msgstr "" + +#: qalculateperiodictabledialog.cpp:229 +msgid "Metal" +msgstr "" + +#: qalculateperiodictabledialog.cpp:230 +msgid "Metalloid" +msgstr "" + +#: qalculateperiodictabledialog.cpp:231 +msgid "Non-Metal" +msgstr "" + +#: qalculateperiodictabledialog.cpp:232 +msgid "Halogen" +msgstr "" + +#: qalculateperiodictabledialog.cpp:233 +msgid "Noble Gas" +msgstr "" + +#: qalculateperiodictabledialog.cpp:234 +msgid "Transactinide" +msgstr "" + +#: qalculateplotdialog.cpp:64 +msgid "Plot" +msgstr "" + +#: qalculateplotdialog.cpp:82 +msgid "Data" +msgstr "" + +#: qalculateplotdialog.cpp:83 +msgid "Function Range" +msgstr "" + +#: qalculateplotdialog.cpp:101 +msgid "Vector/matrix" +msgstr "" + +#: qalculateplotdialog.cpp:104 +msgid "Paired matrix" +msgstr "" + +#: qalculateplotdialog.cpp:107 +msgid "Rows" +msgstr "" + +#: qalculateplotdialog.cpp:109 +msgid "X variable:" +msgstr "" + +#: qalculateplotdialog.cpp:113 +msgid "Style:" +msgstr "" + +#: qalculateplotdialog.cpp:115 +msgid "Line" +msgstr "" + +#: qalculateplotdialog.cpp:116 +msgid "Points" +msgstr "" + +#: qalculateplotdialog.cpp:117 +msgid "Line with points" +msgstr "" + +#: qalculateplotdialog.cpp:118 +msgid "Boxes/bars" +msgstr "" + +#: qalculateplotdialog.cpp:119 +msgid "Histogram" +msgstr "" + +#: qalculateplotdialog.cpp:120 +msgid "Steps" +msgstr "" + +#: qalculateplotdialog.cpp:121 +msgid "Candlesticks" +msgstr "" + +#: qalculateplotdialog.cpp:122 +msgid "Dots" +msgstr "" + +#: qalculateplotdialog.cpp:124 +msgid "Smoothing:" +msgstr "" + +#: qalculateplotdialog.cpp:127 +msgid "Monotonic" +msgstr "" + +#: qalculateplotdialog.cpp:128 +msgid "Natural cubic splines" +msgstr "" + +#: qalculateplotdialog.cpp:129 +msgid "Bezier" +msgstr "" + +#: qalculateplotdialog.cpp:130 +msgid "Bezier (monotonic)" +msgstr "" + +#: qalculateplotdialog.cpp:132 +msgid "Y-axis:" +msgstr "" + +#: qalculateplotdialog.cpp:136 +msgid "Primary" +msgstr "" + +#: qalculateplotdialog.cpp:139 +msgid "Secondary" +msgstr "" + +#: qalculateplotdialog.cpp:171 +msgid "Sampling rate:" +msgstr "" + +#: qalculateplotdialog.cpp:176 +msgid "Step size:" +msgstr "" + +#: qalculateplotdialog.cpp:194 +msgid "Display grid" +msgstr "" + +#: qalculateplotdialog.cpp:196 +msgid "Display full border" +msgstr "" + +#: qalculateplotdialog.cpp:199 +msgid "Logarithmic x scale:" +msgstr "" + +#: qalculateplotdialog.cpp:203 +msgid "Logarithmic y scale:" +msgstr "" + +#: qalculateplotdialog.cpp:207 +msgid "X-axis label:" +msgstr "" + +#: qalculateplotdialog.cpp:210 +msgid "Y-axis label:" +msgstr "" + +#: qalculateplotdialog.cpp:213 +msgid "Color display:" +msgstr "" + +#: qalculateplotdialog.cpp:217 +msgid "Color" +msgstr "" + +#: qalculateplotdialog.cpp:220 +msgid "Monochrome" +msgstr "" + +#: qalculateplotdialog.cpp:224 +msgid "Legend placement:" +msgstr "" + +#: qalculateplotdialog.cpp:227 +msgid "Top-left" +msgstr "" + +#: qalculateplotdialog.cpp:228 +msgid "Top-right" +msgstr "" + +#: qalculateplotdialog.cpp:229 +msgid "Bottom-left" +msgstr "" + +#: qalculateplotdialog.cpp:230 +msgid "Bottom-right" +msgstr "" + +#: qalculateplotdialog.cpp:231 +msgid "Below" +msgstr "" + +#: qalculateplotdialog.cpp:232 +msgid "Outside" +msgstr "" + +#: qalculateplotdialog.cpp:403 qalculateplotdialog.cpp:458 +#: qalculateplotdialog.cpp:506 +msgid "Empty expression." +msgstr "" + +#: qalculateplotdialog.cpp:472 qalculateplotdialog.cpp:519 +msgid "Empty x variable." +msgstr "" + +#: qalculateprecisiondialog.cpp:34 qalculateprecisiondialog.cpp:36 +msgid "Recalculate" +msgstr "" + +#: qalculateprecisiondialog.cpp:41 +msgid "Precision:" +msgstr "" + +#: qalculatepreferencesdialog.cpp:100 +msgid "Choose..." +msgstr "" + +#: qalculatepreferencesdialog.cpp:147 +msgid "Preferences" +msgstr "" + +#: qalculatepreferencesdialog.cpp:161 +msgid "Close to system tray" +msgstr "" + +#: qalculatepreferencesdialog.cpp:162 +msgid "" +"If the application will reside in the system tray when the window is closed" +msgstr "" + +#: qalculatepreferencesdialog.cpp:164 +msgid "Display expression status" +msgstr "" + +#: qalculatepreferencesdialog.cpp:165 +msgid "" +"If as-you-type expression status shall be displayed below the expression " +"entry" +msgstr "" + +#: qalculatepreferencesdialog.cpp:167 +msgid "Use icon buttons" +msgstr "" + +#: qalculatepreferencesdialog.cpp:168 +msgid "" +"Use icons instead of text on the top-right buttons. The third state uses the " +"style setting for icons on buttons." +msgstr "" + +#: qalculatepreferencesdialog.cpp:171 +msgid "Update exchange rates on start" +msgstr "" + +#: qalculatepreferencesdialog.cpp:172 +msgid "" +"If current exchange rates shall be downloaded from the internet at program " +"start" +msgstr "" + +#: qalculatepreferencesdialog.cpp:174 +msgid "Save mode on exit" +msgstr "" + +#: qalculatepreferencesdialog.cpp:175 +msgid "If the mode of the calculator shall be restored" +msgstr "" + +#: qalculatepreferencesdialog.cpp:177 +msgid "Save definitions on exit" +msgstr "" + +#: qalculatepreferencesdialog.cpp:178 +msgid "" +"If changes to functions, units and variables shall be saved automatically" +msgstr "" + +#: qalculatepreferencesdialog.cpp:180 +msgid "Use only keypad keys for RPN" +msgstr "" + +#: qalculatepreferencesdialog.cpp:181 +msgid "" +"Use only keypad keys for RPN operations (+-*/^) and use the rest of the " +"keyboard for expression entry" +msgstr "" + +#: qalculatepreferencesdialog.cpp:183 +msgid "Ignores dots in numbers" +msgstr "" + +#: qalculatepreferencesdialog.cpp:184 +msgid "" +"Allow dots, '.', to be used as thousands separator instead of as an " +"alternative to decimal sign" +msgstr "" + +#: qalculatepreferencesdialog.cpp:187 +msgid "Enable unicode signs" +msgstr "" + +#: qalculatepreferencesdialog.cpp:188 +msgid "Disable this if you have problems with some fancy characters" +msgstr "" + +#: qalculatepreferencesdialog.cpp:190 +msgid "Use lower case in numbers" +msgstr "" + +#: qalculatepreferencesdialog.cpp:191 +msgid "If lower case letters should be used in numbers with non-decimal base" +msgstr "" + +#: qalculatepreferencesdialog.cpp:193 +msgid "Use lower case \"e\"" +msgstr "" + +#: qalculatepreferencesdialog.cpp:194 +msgid "If \"e\"; shall be used instead of \"E\" in numbers" +msgstr "" + +#: qalculatepreferencesdialog.cpp:196 +msgid "Alternative base prefixes" +msgstr "" + +#: qalculatepreferencesdialog.cpp:197 +msgid "" +"If hexadecimal numbers shall be displayed with \"0x0\" and binary numbers " +"with \"0b00\" as prefixes" +msgstr "" + +#: qalculatepreferencesdialog.cpp:199 +msgid "Spell out logical operators" +msgstr "" + +#: qalculatepreferencesdialog.cpp:200 +msgid "If logical and/or shall be displayed as \"&&\"/\"||\" or \"and\"/\"or\"" +msgstr "" + +#: qalculatepreferencesdialog.cpp:203 +msgid "Multiplication sign:" +msgstr "" + +#: qalculatepreferencesdialog.cpp:215 +msgid "Division sign:" +msgstr "" + +#: qalculatepreferencesdialog.cpp:230 +msgid "Custom result font" +msgstr "" + +#: qalculatepreferencesdialog.cpp:234 +msgid "Custom expression font" +msgstr "" + +#: qalculatepreferencesdialog.cpp:238 +msgid "Custom status font" +msgstr "" + +#: qalculatepreferencesdialog.cpp:243 +msgid "Status error color:" +msgstr "" + +#: qalculatepreferencesdialog.cpp:250 +msgid "Status warning color:" +msgstr "" + +#: qalculateresultdisplay.cpp:52 +msgid "a matrix" +msgstr "" + +#: qalculateresultdisplay.cpp:54 +msgid "a vector" +msgstr "" + +#: qalculateresultdisplay.cpp:57 +msgid "double-click to view/edit" +msgstr "" + +#: qalculateresultdisplay.cpp:60 +msgid "Unknown variable" +msgstr "" + +#: qalculateresultdisplay.cpp:72 +msgid "Prefix" +msgstr "" + +#: qalculateresultdisplay.cpp:336 +msgid "Show Parsed Expression" +msgstr "" + +#: qalculateresultdisplay.cpp:342 qalculateresultdisplay.cpp:353 +msgid "Show Object Info" +msgstr "" + +#: qalculateresultdisplay.cpp:348 +msgid "View/Edit Matrix" +msgstr "" + +#: qalculateresultdisplay.cpp:350 +msgid "View/Edit Vector" +msgstr "" + +#: qalculateresultdisplay.cpp:382 +msgid "Parsed expression:" +msgstr "" + +#: qalculatesetbasedialog.cpp:33 +msgid "Result Base" +msgstr "" + +#: qalculatesetbasedialog.cpp:39 qalculatesetbasedialog.cpp:52 +msgid "Other:" +msgstr "" + +#: qalculatesetbasedialog.cpp:43 +msgid "Time format" +msgstr "" + +#: qalculatesetbasedialog.cpp:44 qalculatesetbasedialog.cpp:55 +msgid "Roman numerals" +msgstr "" + +#: qalculatesetbasedialog.cpp:46 +msgid "Expression Base" +msgstr "" + +#: qalculateunitsdialog.cpp:54 +msgid "Units" +msgstr "" + +#: qalculateunitsdialog.cpp:68 +msgid "Names" +msgstr "" + +#: qalculateunitsdialog.cpp:69 +msgid "Base" +msgstr "" + +#: qalculateunitsdialog.cpp:72 +msgid "Conversion" +msgstr "" + +#: qalculateunitsdialog.cpp:105 +msgid "Convert Result" +msgstr "" + +#: qalculateunitsdialog.cpp:250 +msgid "Cannot delete unit as it is needed by other units." +msgstr "" + +#: qalculatevariablesdialog.cpp:51 +msgid "Variables" +msgstr "" + +#: qalculatevariablesdialog.cpp:60 +msgid "Variable Name" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 5 +#: rc.cpp:6 +#, no-c-format +msgid "&New" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 37 +#: rc.cpp:12 +#, no-c-format +msgid "&Set Prefix" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 39 +#: rc.cpp:15 +#, no-c-format +msgid "&Convert To Unit" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 54 +#: rc.cpp:18 +#, no-c-format +msgid "&Mode" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 55 +#: rc.cpp:21 +#, no-c-format +msgid "Number Base" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 67 +#: rc.cpp:24 +#, no-c-format +msgid "Numerical Display" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 80 +#: rc.cpp:27 +#, no-c-format +msgid "Fractional Display" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 86 +#: rc.cpp:30 +#, no-c-format +msgid "Unit Display" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 96 +#: rc.cpp:33 +#, no-c-format +msgid "Angle Unit" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 104 +#: rc.cpp:36 +#, no-c-format +msgid "Enabled Objects" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 121 +#: rc.cpp:42 +#, no-c-format +msgid "Assumptions" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 137 +#: rc.cpp:45 +#, no-c-format +msgid "Algebraic Mode" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 161 +#: rc.cpp:51 +#, no-c-format +msgid "Fu&nctions" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 163 +#: rc.cpp:54 +#, no-c-format +msgid "&Variables" +msgstr "" + +#. i18n: file ./qalculate_kdeui.rc line 165 +#: rc.cpp:57 +#, no-c-format +msgid "&Units" +msgstr "" diff --git a/po/sv.po b/po/sv.po new file mode 100644 index 0000000..031d43f --- /dev/null +++ b/po/sv.po @@ -0,0 +1,2615 @@ +# translation of sv.po to Swedish +# Niklas Knutsson , 2005. +msgid "" +msgstr "" +"Project-Id-Version: sv\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2007-05-08 14:44+0200\n" +"PO-Revision-Date: 2006-04-29 23:40+0200\n" +"Last-Translator: Niklas Knutsson \n" +"Language-Team: Swedish\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: _translatorinfo.cpp:1 +msgid "" +"_: NAME OF TRANSLATORS\n" +"Your names" +msgstr "Niklas Knutsson" + +#: _translatorinfo.cpp:3 +msgid "" +"_: EMAIL OF TRANSLATORS\n" +"Your emails" +msgstr "nq@altern.org" + +#: kqalculate.cpp:264 +msgid "Remove from System Tray" +msgstr "Ta bort från aktivitetsfältet" + +#: kqalculate.cpp:265 qalculateeditdatasetdialog.cpp:471 +#: qalculateplotdialog.cpp:226 +msgid "Hide" +msgstr "Göm" + +#: kqalculate.cpp:286 kqalculate.cpp:4484 kqalculate.cpp:5915 +msgid "Enter" +msgstr "" + +#: kqalculate.cpp:287 kqalculate.cpp:513 kqalculate.cpp:4485 +#: kqalculate.cpp:4492 kqalculate.cpp:5916 +msgid "=" +msgstr "" + +#: kqalculate.cpp:289 kqalculate.cpp:514 kqalculate.cpp:4489 +#: kqalculate.cpp:4490 +msgid "Calculate expression and add to stack" +msgstr "Beräkna uttrycket och lägg till i stacken" + +#: kqalculate.cpp:290 kqalculate.cpp:515 kqalculate.cpp:4493 +#: kqalculate.cpp:4494 +msgid "Calculate expression" +msgstr "Beräkna uttrycket" + +#: kqalculate.cpp:296 kqalculate.cpp:5918 +msgid "Store" +msgstr "Spara" + +#: kqalculate.cpp:298 +msgid "Store result as variable" +msgstr "Spara resultatet som en variabel" + +#: kqalculate.cpp:301 kqalculate.cpp:5920 qalculateconvertunitsdialog.cpp:42 +msgid "Convert" +msgstr "Omvandla" + +#: kqalculate.cpp:303 +msgid "Convert units in result" +msgstr "Omvandla enheter i resultatet" + +#: kqalculate.cpp:313 +msgid "Enter expression here" +msgstr "Skriv in uttryck här" + +#: kqalculate.cpp:322 +msgid "status" +msgstr "status" + +#: kqalculate.cpp:354 qalculateeditdataobjectdialog.cpp:71 +msgid "Exact" +msgstr "Exakt" + +#: kqalculate.cpp:355 +msgid "Toggle exact mode" +msgstr "(Av)aktivera exakt läge" + +#: kqalculate.cpp:358 kqalculate.cpp:1070 +msgid "Fraction" +msgstr "Bråktal" + +#: kqalculate.cpp:359 +msgid "Toggle fractional display" +msgstr "(Av)aktivera bråktalsvisning" + +#: kqalculate.cpp:363 +msgid "Numerical display" +msgstr "Numerisk visning" + +#: kqalculate.cpp:366 kqalculate.cpp:1046 qalculateresultdisplay.cpp:288 +msgid "Normal" +msgstr "Normal" + +#: kqalculate.cpp:367 kqalculate.cpp:1048 qalculateresultdisplay.cpp:291 +msgid "Engineering" +msgstr "Teknisk" + +#: kqalculate.cpp:368 kqalculate.cpp:1050 qalculateresultdisplay.cpp:294 +msgid "Scientific" +msgstr "Vetenskaplig" + +#: kqalculate.cpp:369 +msgid "Pure" +msgstr "Strik" + +#: kqalculate.cpp:370 kqalculate.cpp:1054 +msgid "Simple" +msgstr "Enkel" + +#: kqalculate.cpp:372 +msgid "Base in result" +msgstr "Nummerbas i resultatet" + +#: kqalculate.cpp:376 kqalculate.cpp:1029 qalculatesetbasedialog.cpp:35 +#: qalculatesetbasedialog.cpp:48 +msgid "Binary" +msgstr "Binär" + +#: kqalculate.cpp:377 kqalculate.cpp:1031 qalculatesetbasedialog.cpp:36 +#: qalculatesetbasedialog.cpp:49 +msgid "Octal" +msgstr "Oktal" + +#: kqalculate.cpp:378 kqalculate.cpp:1033 kqalculate.cpp:1066 +#: qalculatesetbasedialog.cpp:37 qalculatesetbasedialog.cpp:50 +msgid "Decimal" +msgstr "Decimal" + +#: kqalculate.cpp:379 kqalculate.cpp:1035 qalculatesetbasedialog.cpp:38 +#: qalculatesetbasedialog.cpp:51 +msgid "Hexadecimal" +msgstr "Hexadecimal" + +#: kqalculate.cpp:380 kqalculate.cpp:1039 qalculatesetbasedialog.cpp:42 +msgid "Sexagesimal" +msgstr "Sexagesimal" + +#: kqalculate.cpp:381 kqalculate.cpp:1041 +msgid "Time Format" +msgstr "Tidsformat" + +#: kqalculate.cpp:383 kqalculate.cpp:1037 +msgid "Other..." +msgstr "Annan..." + +#: kqalculate.cpp:389 +msgid "f(x)" +msgstr "" + +#: kqalculate.cpp:393 +msgid "Open functions manager" +msgstr "Öppna funktionshanteraren" + +#: kqalculate.cpp:395 +msgid "sqrt" +msgstr "" + +#: kqalculate.cpp:396 +msgid "Square root" +msgstr "Kvadratrot" + +#: kqalculate.cpp:399 kqalculate.cpp:947 +msgid "xy" +msgstr "" + +#: kqalculate.cpp:400 +msgid "Raise (Ctrl+*)" +msgstr "Upphöj (Ctrl+*)" + +#: kqalculate.cpp:403 kqalculate.cpp:946 +msgid "x2" +msgstr "" + +#: kqalculate.cpp:404 +msgid "Square" +msgstr "Kvadrat" + +#: kqalculate.cpp:406 +msgid "log" +msgstr "" + +#: kqalculate.cpp:407 +msgid "Base-10 logarithm" +msgstr "Bas-10-logaritm" + +#: kqalculate.cpp:409 +msgid "ln" +msgstr "" + +#: kqalculate.cpp:410 +msgid "Natural logarithm" +msgstr "Naturlig logaritm" + +#: kqalculate.cpp:412 +msgid "x!" +msgstr "" + +#: kqalculate.cpp:413 +msgid "Factorial" +msgstr "Fakultet" + +#: kqalculate.cpp:415 +msgid "cos" +msgstr "" + +#: kqalculate.cpp:416 +msgid "Cosine" +msgstr "Cosinus" + +#: kqalculate.cpp:418 +msgid "tan" +msgstr "" + +#: kqalculate.cpp:419 +msgid "Tangent" +msgstr "Tangens" + +#: kqalculate.cpp:421 +msgid "hyp" +msgstr "" + +#: kqalculate.cpp:422 +msgid "Toggle hyperbolic functions" +msgstr "(Av)aktivera hyperbola funktioner" + +#: kqalculate.cpp:425 +msgid "inv" +msgstr "" + +#: kqalculate.cpp:426 +msgid "Toggle inverse functions" +msgstr "(Av)aktivera inversa funktioner" + +#: kqalculate.cpp:429 +msgid "sin" +msgstr "" + +#: kqalculate.cpp:430 +msgid "Sine" +msgstr "Sinus" + +#: kqalculate.cpp:435 +msgid "Deg" +msgstr "" + +#: kqalculate.cpp:436 +msgid "Angle Unit: Degrees" +msgstr "Vinkelenhet: Grader" + +#: kqalculate.cpp:439 +msgid "Rad" +msgstr "" + +#: kqalculate.cpp:440 +msgid "Angle Unit: Radians" +msgstr "Vinkelenhet: Radianer" + +#: kqalculate.cpp:443 +msgid "Gra" +msgstr "" + +#: kqalculate.cpp:444 +msgid "Angle Unit: Gradians" +msgstr "Vinkelenhet: Gradienter" + +#: kqalculate.cpp:447 kqalculate.cpp:1094 kqalculate.cpp:1152 +#: qalculateplotdialog.cpp:126 +msgid "None" +msgstr "Ingen" + +#: kqalculate.cpp:464 +msgid "7" +msgstr "" + +#: kqalculate.cpp:466 +msgid "8" +msgstr "" + +#: kqalculate.cpp:468 +msgid "9" +msgstr "" + +#: kqalculate.cpp:470 +msgid "4" +msgstr "" + +#: kqalculate.cpp:472 +msgid "5" +msgstr "" + +#: kqalculate.cpp:474 +msgid "6" +msgstr "" + +#: kqalculate.cpp:476 +msgid "1" +msgstr "" + +#: kqalculate.cpp:478 +msgid "2" +msgstr "" + +#: kqalculate.cpp:480 +msgid "3" +msgstr "" + +#: kqalculate.cpp:482 +msgid "0" +msgstr "" + +#: kqalculate.cpp:485 +msgid "Decimal point" +msgstr "Decimalkomma" + +#: kqalculate.cpp:487 +msgid "EXP" +msgstr "" + +#: kqalculate.cpp:488 +msgid "10^x (Ctrl+Shift+E)" +msgstr "" + +#: kqalculate.cpp:491 +msgid "Del" +msgstr "" + +#: kqalculate.cpp:494 +msgid "AC" +msgstr "" + +#: kqalculate.cpp:498 +msgid "Multiply" +msgstr "Multiplicera" + +#: kqalculate.cpp:501 +msgid "Divide" +msgstr "Dela" + +#: kqalculate.cpp:507 +msgid "Subtract" +msgstr "Subtrahera" + +#: kqalculate.cpp:509 +msgid "Ans" +msgstr "" + +#: kqalculate.cpp:510 +msgid "Previous result" +msgstr "Föregående resultat" + +#: kqalculate.cpp:512 kqalculate.cpp:4488 +msgid "Ent" +msgstr "" + +#: kqalculate.cpp:535 +msgid "Index" +msgstr "" + +#: kqalculate.cpp:536 qalculateeditdataobjectdialog.cpp:49 +#: qalculatevariablesdialog.cpp:61 +msgid "Value" +msgstr "Värde" + +#: kqalculate.cpp:555 kqalculate.cpp:5924 +msgid "Up" +msgstr "Upp" + +#: kqalculate.cpp:556 +msgid "Move selected register up" +msgstr "Flytta valt register uppåt" + +#: kqalculate.cpp:560 kqalculate.cpp:5926 +msgid "Down" +msgstr "Ned" + +#: kqalculate.cpp:561 +msgid "Move selected register down" +msgstr "Flytta valt register nedåt" + +#: kqalculate.cpp:566 +msgid "Edit value of selected register" +msgstr "Redigera värdet för valt register" + +#: kqalculate.cpp:571 +msgid "Delete selected register" +msgstr "Ta bort valt register" + +#: kqalculate.cpp:576 +msgid "Clear the RPN stack" +msgstr "Töm RPN-stacken" + +#: kqalculate.cpp:592 +msgid "Keypad" +msgstr "Knappsats" + +#: kqalculate.cpp:593 +msgid "Show/hide keypad" +msgstr "Visa/göm knappsats" + +#: kqalculate.cpp:596 +msgid "History" +msgstr "Historik" + +#: kqalculate.cpp:597 +msgid "Show/hide history" +msgstr "Visa/göm historik" + +#: kqalculate.cpp:600 +msgid "RPN Stack" +msgstr "RPN-stack" + +#: kqalculate.cpp:601 +msgid "Show/hide RPN stack" +msgstr "Visa/göm RPN-stacken" + +#: kqalculate.cpp:716 kqalculate.cpp:2527 +msgid "RPN Register Moved" +msgstr "RPN-register flyttades" + +#: kqalculate.cpp:752 kqalculate.cpp:784 kqalculate.cpp:2138 +#: kqalculate.cpp:2702 kqalculate.cpp:2739 +msgid "approx." +msgstr "ca" + +#: kqalculate.cpp:894 kqalculate.cpp:4813 +msgid "Load meta mode: %1" +msgstr "Ladda metaläge: %1" + +#: kqalculate.cpp:966 +msgid "Qalculate! - Scientific Calculator" +msgstr "Qalculate! - Vetenskaplig kalkulator" + +#: kqalculate.cpp:985 qalculateeditfunctiondialog.cpp:601 +#: qalculateresultdisplay.cpp:62 +msgid "Variable" +msgstr "Variabel" + +#: kqalculate.cpp:986 qalculateeditfunctiondialog.cpp:596 +#: qalculateeditmatrixvectordialog.cpp:106 qalculateimportcsvdialog.cpp:52 +#: qalculateinsertmatrixvectordialog.cpp:85 +#: qalculateinsertmatrixvectordialog.cpp:310 +msgid "Matrix" +msgstr "Matris" + +#: kqalculate.cpp:987 qalculateeditfunctiondialog.cpp:595 +#: qalculateeditmatrixvectordialog.cpp:109 +#: qalculateinsertmatrixvectordialog.cpp:88 +#: qalculateinsertmatrixvectordialog.cpp:308 +msgid "Vector" +msgstr "Vektor" + +#: kqalculate.cpp:988 +msgid "Unknown Variable" +msgstr "Okänd variabel" + +#: kqalculate.cpp:989 qalculateeditdatasetdialog.cpp:70 +#: qalculateeditfunctiondialog.cpp:71 qalculateeditfunctiondialog.cpp:599 +#: qalculateplotdialog.cpp:98 qalculateresultdisplay.cpp:92 +msgid "Function" +msgstr "Funktion" + +#: kqalculate.cpp:990 qalculatedatasetsdialog.cpp:64 +msgid "Data Set" +msgstr "Dataset" + +#: kqalculate.cpp:991 qalculateconvertunitsdialog.cpp:68 +#: qalculateeditfunctiondialog.cpp:600 qalculateresultdisplay.cpp:67 +#: qalculateunitsdialog.cpp:67 +msgid "Unit" +msgstr "Enhet" + +#: kqalculate.cpp:992 +msgid "Import CSV File..." +msgstr "Importera CSV-fil..." + +#: kqalculate.cpp:993 +msgid "Export CSV File..." +msgstr "Exportera CSV-fil..." + +#: kqalculate.cpp:994 +msgid "Store Result..." +msgstr "Spara resultatet..." + +#: kqalculate.cpp:995 +msgid "Save Result Image..." +msgstr "Spara resultatbild..." + +#: kqalculate.cpp:996 +msgid "Save Definitions" +msgstr "Spara definitioner" + +#: kqalculate.cpp:997 +msgid "Update Exchange Rates" +msgstr "Uppdatera växelkurser" + +#: kqalculate.cpp:998 +msgid "Plot Functions/Data" +msgstr "Rita functions-/datadiagram" + +#: kqalculate.cpp:1000 +msgid "Convert Number Bases" +msgstr "Omvandla mellan nummerbaser" + +#: kqalculate.cpp:1001 qalculateperiodictabledialog.cpp:40 +msgid "Periodic Table" +msgstr "Periodiska systemet" + +#: kqalculate.cpp:1008 +msgid "Show/hide main Qalculate! window" +msgstr "Visa/dölj Qalculate!:s huvudfönster" + +#: kqalculate.cpp:1011 +msgid "Configure &Global Shortcuts..." +msgstr "Anpassa &globala snabbtangenter..." + +#: kqalculate.cpp:1013 +msgid "Manage Variables" +msgstr "Hantera variabler" + +#: kqalculate.cpp:1014 +msgid "Manage Functions" +msgstr "Hantera funktioner" + +#: kqalculate.cpp:1015 +msgid "Manage Units" +msgstr "Hantera enheter" + +#: kqalculate.cpp:1016 +msgid "Manage Data Sets" +msgstr "Hantera dataset" + +#: kqalculate.cpp:1017 kqalculate.cpp:1150 +msgid "Factorize" +msgstr "Faktorisera" + +#: kqalculate.cpp:1018 kqalculate.cpp:1148 +msgid "Simplify" +msgstr "Förenkla" + +#: kqalculate.cpp:1019 +msgid "Set Unknowns..." +msgstr "Ange okända värden..." + +#: kqalculate.cpp:1020 +msgid "Convert to Unit Expression..." +msgstr "Omvandla till enhetsuttryck" + +#: kqalculate.cpp:1021 kqalculate.cpp:1084 +msgid "Convert to Base Units" +msgstr "Omvandla till basenheter" + +#: kqalculate.cpp:1022 kqalculate.cpp:1086 +msgid "Convert to Best Unit" +msgstr "Omvandla till lämpligast enhet" + +#: kqalculate.cpp:1023 +msgid "Insert Matrix..." +msgstr "Infoga matris..." + +#: kqalculate.cpp:1024 +msgid "Insert Vector..." +msgstr "Infoga vektor..." + +#: kqalculate.cpp:1025 +msgid "Copy Result" +msgstr "Kopiera resultatet" + +#: kqalculate.cpp:1026 +msgid "Clear History" +msgstr "Töm historiken" + +#: kqalculate.cpp:1027 +msgid "Configure Qalculate!" +msgstr "Anpassa Qalculate!" + +#: kqalculate.cpp:1043 +msgid "Roman Numerals" +msgstr "Romerska siffror" + +#: kqalculate.cpp:1045 +msgid "Select Result and Expression Base..." +msgstr "Välj bas i resultat och uttryck..." + +#: kqalculate.cpp:1052 +msgid "Purely Scientific" +msgstr "Strikt vetenskapligt" + +#: kqalculate.cpp:1056 +msgid "Indicate Infinite Series" +msgstr "Indikera oändliga talserier" + +#: kqalculate.cpp:1058 +msgid "Sort Minus Last" +msgstr "Sortera minus sist" + +#: kqalculate.cpp:1060 +msgid "Negative Exponents" +msgstr "Negativa exponenter" + +#: kqalculate.cpp:1062 +msgid "Show Ending Zeroes" +msgstr "Visa avslutande nollor" + +#: kqalculate.cpp:1064 +msgid "Round Halfway Numbers to Even" +msgstr "Avrunda mittimellan-tal till jämn siffra" + +#: kqalculate.cpp:1068 +msgid "Decimal (Try Exact)" +msgstr "Decimal (försök exakt)" + +#: kqalculate.cpp:1072 +msgid "Combined" +msgstr "Kombinerad" + +#: kqalculate.cpp:1074 +msgid "Enable Prefixes" +msgstr "Använd prefix" + +#: kqalculate.cpp:1076 +msgid "Enable Use of All SI Prefixes" +msgstr "Automatisk användning av alla SI-prefix" + +#: kqalculate.cpp:1078 +msgid "Enable Denominator Prefixes" +msgstr "Aktivera prefix i nämnaren" + +#: kqalculate.cpp:1080 +msgid "Place Units Separately" +msgstr "Placera enheter separat" + +#: kqalculate.cpp:1082 +msgid "No Automatic Conversion" +msgstr "Ingen automatisk omvandling" + +#: kqalculate.cpp:1088 +msgid "Degrees" +msgstr "Grader" + +#: kqalculate.cpp:1090 +msgid "Radians" +msgstr "Radianer" + +#: kqalculate.cpp:1092 +msgid "Gradians" +msgstr "Gradienter" + +#: kqalculate.cpp:1096 +msgid "Abbreviate Names" +msgstr "Förkorta namn" + +#: kqalculate.cpp:1098 +msgid "Enable Variables" +msgstr "Aktivera variabler" + +#: kqalculate.cpp:1100 +msgid "Enable Functions" +msgstr "Aktivera funktioner" + +#: kqalculate.cpp:1102 +msgid "Enable Units" +msgstr "Aktivera enheter" + +#: kqalculate.cpp:1104 +msgid "Enable Unknowns" +msgstr "Aktivera okända" + +#: kqalculate.cpp:1106 +msgid "Calculate Variables" +msgstr "Beräkna variabler" + +#: kqalculate.cpp:1108 +msgid "Allow Complex Result" +msgstr "Tillåt complext resultat" + +#: kqalculate.cpp:1110 +msgid "Allow Infinite Result" +msgstr "Tillåt oändligt resultat" + +#: kqalculate.cpp:1112 +msgid "Try Exact" +msgstr "Försök exakt" + +#: kqalculate.cpp:1114 +msgid "Always Exact" +msgstr "Alltid exakt" + +#: kqalculate.cpp:1116 qalculateeditdataobjectdialog.cpp:70 +msgid "Approximate" +msgstr "Approximera" + +#: kqalculate.cpp:1118 kqalculate.cpp:1132 +#: qalculateeditunknownvariabledialog.cpp:65 +#: qalculateeditunknownvariabledialog.cpp:78 +#: qalculateperiodictabledialog.cpp:235 +msgid "Unknown" +msgstr "Ökänd" + +#: kqalculate.cpp:1120 qalculateeditunknownvariabledialog.cpp:66 +msgid "Not Matrix" +msgstr "Inte matris" + +#: kqalculate.cpp:1122 qalculateeditdatasetdialog.cpp:468 +#: qalculateeditfunctiondialog.cpp:590 +#: qalculateeditunknownvariabledialog.cpp:67 +msgid "Number" +msgstr "Nummer" + +#: kqalculate.cpp:1124 +msgid "Complex" +msgstr "Komplex" + +#: kqalculate.cpp:1126 +msgid "Real" +msgstr "Reell" + +#: kqalculate.cpp:1128 +msgid "Rational" +msgstr "Rationell" + +#: kqalculate.cpp:1130 qalculateeditfunctiondialog.cpp:591 +#: qalculateeditunknownvariabledialog.cpp:71 +msgid "Integer" +msgstr "Heltal" + +#: kqalculate.cpp:1134 qalculateeditunknownvariabledialog.cpp:83 +msgid "Non-Zero" +msgstr "Ej noll" + +#: kqalculate.cpp:1136 qalculateeditunknownvariabledialog.cpp:79 +msgid "Positive" +msgstr "Positiv" + +#: kqalculate.cpp:1138 qalculateeditunknownvariabledialog.cpp:80 +msgid "Non-Negative" +msgstr "Ej negativ" + +#: kqalculate.cpp:1140 qalculateeditunknownvariabledialog.cpp:81 +msgid "Negative" +msgstr "Negativ" + +#: kqalculate.cpp:1142 qalculateeditunknownvariabledialog.cpp:82 +msgid "Non-Positive" +msgstr "Ej positiv" + +#: kqalculate.cpp:1144 +msgid "Non-Zero Denominators" +msgstr "Nämnare ej noll" + +#: kqalculate.cpp:1146 +msgid "Warn About Denominators Assumed Non-Zero" +msgstr "Varna om nämnare antagna som ej noll" + +#: kqalculate.cpp:1154 +msgid "Read Precision" +msgstr "Läs precision" + +#: kqalculate.cpp:1156 +msgid "Limit Implicit Multiplication" +msgstr "Begränsa implicit multiplikation" + +#: kqalculate.cpp:1158 +msgid "RPN Mode" +msgstr "RPN läge" + +#: kqalculate.cpp:1160 +msgid "RPN Syntax" +msgstr "RPN-syntax" + +#: kqalculate.cpp:1162 qalculateprecisiondialog.cpp:31 +msgid "Precision" +msgstr "Precision" + +#: kqalculate.cpp:1163 qalculatedecimalsdialog.cpp:27 +msgid "Decimals" +msgstr "Decimaler" + +#: kqalculate.cpp:1164 +msgid "Save Mode..." +msgstr "Spara läge..." + +#: kqalculate.cpp:1165 +msgid "Delete Mode..." +msgstr "Radera läge..." + +#: kqalculate.cpp:1167 +msgid "Save Default Mode" +msgstr "Spara förvalt läge" + +#: kqalculate.cpp:1168 +msgid "Clear Stack" +msgstr "Töm stacken" + +#: kqalculate.cpp:1172 +msgid "Exp RPN Operation" +msgstr "Exp RPN-operation" + +#: kqalculate.cpp:1860 +msgid "and" +msgstr "och" + +#: kqalculate.cpp:1865 +msgid "or" +msgstr "eller" + +#: kqalculate.cpp:2122 +msgid "undefined" +msgstr "odefinierad" + +#: kqalculate.cpp:2164 +msgid "EXACT" +msgstr "EXAKT" + +#: kqalculate.cpp:2167 +msgid "APPROX" +msgstr "APPROX" + +#: kqalculate.cpp:2171 +msgid "RPN" +msgstr "RPN" + +#: kqalculate.cpp:2179 +msgid "BIN" +msgstr "BIN" + +#: kqalculate.cpp:2184 +msgid "OCT" +msgstr "OKT" + +#: kqalculate.cpp:2189 +msgid "HEX" +msgstr "HEX" + +#: kqalculate.cpp:2194 +msgid "ROMAN" +msgstr "ROMERSKA" + +#: kqalculate.cpp:2206 +msgid "DEG" +msgstr "DEG" + +#: kqalculate.cpp:2211 +msgid "RAD" +msgstr "RAD" + +#: kqalculate.cpp:2216 +msgid "GRA" +msgstr "GRA" + +#: kqalculate.cpp:2223 +msgid "PREC" +msgstr "PREC" + +#: kqalculate.cpp:2228 +msgid "FUNC" +msgstr "FUNK" + +#: kqalculate.cpp:2234 +msgid "UNIT" +msgstr "ENHET" + +#: kqalculate.cpp:2240 +msgid "VAR" +msgstr "VAR" + +#: kqalculate.cpp:2246 +msgid "INF" +msgstr "INF" + +#: kqalculate.cpp:2252 +msgid "CPLX" +msgstr "KPLX" + +#: kqalculate.cpp:2333 kqalculate.cpp:2351 kqalculate.cpp:2581 +msgid "aborted" +msgstr "avbruten" + +#: kqalculate.cpp:2352 +msgid "calculation was aborted" +msgstr "beräkningen avbröts" + +#: kqalculate.cpp:2588 +msgid "result processing was aborted" +msgstr "resultatbehandlingen avbröts" + +#: kqalculate.cpp:2636 +msgid "Processing..." +msgstr "Behandlar..." + +#: kqalculate.cpp:2640 kqalculate.cpp:2885 kqalculate.cpp:3145 +msgid "Abort" +msgstr "Avbryt" + +#: kqalculate.cpp:2873 +msgid "Factorizing..." +msgstr "Faktoriserar..." + +#: kqalculate.cpp:2877 +msgid "Simplifying..." +msgstr "Förenklar..." + +#: kqalculate.cpp:3141 +msgid "Calculating..." +msgstr "Beräknar..." + +#: kqalculate.cpp:3191 +msgid "RPN Operation" +msgstr "RPN-operation" + +#: kqalculate.cpp:3259 +msgid "Errors" +msgstr "Fel" + +#: kqalculate.cpp:3260 +msgid "Warnings" +msgstr "Varningar" + +#: kqalculate.cpp:3270 +msgid "Couldn't write definitions" +msgstr "Kunde inte spara definitioner" + +#: kqalculate.cpp:3538 +msgid "Prefixes" +msgstr "Prefix" + +#: kqalculate.cpp:3665 +msgid "No Prefix" +msgstr "Inget prefix" + +#: kqalculate.cpp:3816 qalculatevariablesdialog.cpp:191 +#: qalculatevariablesdialog.cpp:337 +msgid "Variable does not exist anymore." +msgstr "Variabeln existerar inte längre." + +#: kqalculate.cpp:3832 qalculateconvertunitsdialog.cpp:153 +#: qalculateunitsdialog.cpp:223 qalculateunitsdialog.cpp:337 +msgid "Unit does not exist anymore." +msgstr "Enheten existerar inte längre." + +#: kqalculate.cpp:3905 +msgid "Failed to download exchange rates from ECB." +msgstr "Misslyckades med att hämta växelkurser från ECB." + +#: kqalculate.cpp:4752 +msgid "Save Mode" +msgstr "Spara läge" + +#: kqalculate.cpp:4755 +msgid "Mode name:" +msgstr "Lägesnamn:" + +#: kqalculate.cpp:4765 +msgid "Shortcut:" +msgstr "Snabbtangent:" + +#: kqalculate.cpp:4792 +msgid "Empty mode name." +msgstr "Tomt fält för lägesnamn" + +#: kqalculate.cpp:4795 +msgid "Preset mode cannot be overwritten." +msgstr "Förinställt läge kan inte skrivas över." + +#: kqalculate.cpp:4827 +msgid "Delete Mode" +msgstr "Radera läge" + +#: kqalculate.cpp:4827 +msgid "Mode:" +msgstr "Läge:" + +#: kqalculate.cpp:5001 +msgid "log10 function not found." +msgstr "Kunde inte finna log10 funktionen." + +#: kqalculate.cpp:5545 main.cpp:156 main.cpp:159 main.cpp:160 main.cpp:161 +#: main.cpp:162 +msgid "Temporary" +msgstr "Temporära" + +#: kqalculate.cpp:5567 kqalculate.cpp:5594 qalculatefunctionsdialog.cpp:191 +#: qalculatefunctionsdialog.cpp:300 +msgid "Function does not exist anymore." +msgstr "Funktionen existerar inte längre." + +#: kqalculate.cpp:5697 kqalculate.cpp:5733 +msgid "My Variables" +msgstr "Mina variabler" + +#: kqalculate.cpp:5709 qalculateimportcsvdialog.cpp:56 +msgid "Vectors" +msgstr "Vektorer" + +#: kqalculate.cpp:5721 +msgid "Matrices" +msgstr "Matriser" + +#: kqalculate.cpp:5762 qalculateplotdialog.cpp:726 +msgid "Save Image" +msgstr "Spara bild" + +#: kqalculate.cpp:5767 qalculateplotdialog.cpp:731 +msgid "" +"A file named \"%1\" already exists. Are you sure you want to overwrite it?" +msgstr "En fil med namnet \"%i\" finns redan. Vill du ersätta den?" + +#: kqalculate.cpp:5767 qalculateplotdialog.cpp:731 +msgid "Overwrite File?" +msgstr "Ersätt filen" + +#: kqalculate.cpp:5767 qalculateplotdialog.cpp:731 +msgid "&Overwrite" +msgstr "Ersätt" + +#: kqalculate.cpp:5801 +msgid "Failed to save image." +msgstr "Misslyckedes med att spara bild." + +#: kqalculate.cpp:6027 +msgid "No unknowns in result." +msgstr "Ingen okända värden i resultatet." + +#: kqalculate.cpp:6030 +msgid "Set Unknowns" +msgstr "Ange okända värden" + +#: kqalculate.cpp:6194 +msgid "Too many arguments for %1()." +msgstr "För många parametrar för %1()" + +#: kqalculate.cpp:6220 qalculatedatasetsdialog.cpp:342 +#: qalculatefunctionsdialog.cpp:343 qalculateresultdisplay.cpp:120 +msgid "argument" +msgstr "parameter" + +#: kqalculate.cpp:6442 kqalculate.cpp:6446 +msgid "Edit Expression" +msgstr "Redigera uttrycket" + +#: kqalculate.cpp:6451 +msgid "Edit Result" +msgstr "Redigera namnet" + +#: kqalculate.cpp:6454 +msgid "Insert Result Variable" +msgstr "Infoga resultatvariabel" + +#: main.cpp:45 +msgid "A powerful and easy to use desktop calculator" +msgstr "En kraftfull och användarvänlig miniräknare" + +#: main.cpp:51 +msgid "Calculate X11-clipboard content (selected text)" +msgstr "Beräkna X11-klippbordets innehåll (vald text)" + +#: main.cpp:52 +msgid "Initial expression to calculate" +msgstr "Initialt uttryck att beräkna" + +#: main.cpp:134 +msgid "Enter a mathematical expression above.
Ex. 5 + 2 / 3" +msgstr "Skriv in ett matematiskt uttryck ovan.
Ex. 5 + 2 / 3" + +#: main.cpp:143 +msgid "" +"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" +"\n" +"Do you want to fetch exchange rates now from the Internet?" +msgstr "" +"Du behöver ladda ner växelkurser för att kunna omvandla mellan olika " +"valutor. Du kan senare hämta nuvarande växelkurser genom välja \"Uppdatera " +"växelkurser\" under filmenyn.\n" +"\n" +"Vill du hämta växelkurser från Internet nu?" + +#: main.cpp:143 +msgid "Update exchange rates?" +msgstr "Uppdatera växelkurser?" + +#: main.cpp:155 +msgid "ans" +msgstr "" + +#: main.cpp:156 +msgid "Last Answer" +msgstr "Senaste svaret" + +#: main.cpp:157 +msgid "answer" +msgstr "svar" + +#: main.cpp:159 +msgid "Answer 2" +msgstr "Svar 2" + +#: main.cpp:160 +msgid "Answer 3" +msgstr "Svar 3" + +#: main.cpp:161 +msgid "Answer 4" +msgstr "Svar 4" + +#: main.cpp:162 +msgid "Answer 5" +msgstr "Svar 5" + +#: main.cpp:166 +msgid "Failed to load global definitions!" +msgstr "Fel vid inhämtande av systemvida definitioner!" + +#: main.cpp:290 +msgid "Qalculate!" +msgstr "" + +#: preferences.cpp:208 +msgid "Preset" +msgstr "Förinställt" + +#: preferences.cpp:669 +#, c-format +msgid "" +"Couldn't write preferences to\n" +"%s" +msgstr "" +"Kunde inte spara inställningar till\n" +"%s" + +#: qalculateconvertnumberbasesdialog.cpp:31 qalculatesetbasedialog.cpp:29 +msgid "Number Bases" +msgstr "Nummerbaser" + +#: qalculateconvertnumberbasesdialog.cpp:37 +msgid "Decimal:" +msgstr "Decimalt:" + +#: qalculateconvertnumberbasesdialog.cpp:41 +msgid "Binary:" +msgstr "Binärt:" + +#: qalculateconvertnumberbasesdialog.cpp:45 +msgid "Octal:" +msgstr "Oktalt:" + +#: qalculateconvertnumberbasesdialog.cpp:49 +msgid "Hexadecimal:" +msgstr "Hexadecimalt:" + +#: qalculateconvertunitsdialog.cpp:44 +msgid "Selector" +msgstr "Väljare" + +#: qalculateconvertunitsdialog.cpp:50 qalculateeditdatasetdialog.cpp:482 +msgid "Unit expression:" +msgstr "Enhetsuttryck:" + +#: qalculateconvertunitsdialog.cpp:63 qalculatefunctionsdialog.cpp:55 +#: qalculateunitsdialog.cpp:63 qalculatevariablesdialog.cpp:57 +msgid "Category" +msgstr "Kategori" + +#: qalculateconvertunitsdialog.cpp:85 qalculateconvertunitsdialog.cpp:86 +#: qalculateconvertunitsdialog.cpp:141 qalculateconvertunitsdialog.cpp:180 +#: qalculatefunctionsdialog.cpp:118 qalculatefunctionsdialog.cpp:119 +#: qalculatefunctionsdialog.cpp:183 qalculatefunctionsdialog.cpp:505 +#: qalculateunitsdialog.cpp:150 qalculateunitsdialog.cpp:151 +#: qalculateunitsdialog.cpp:215 qalculateunitsdialog.cpp:416 +#: qalculatevariablesdialog.cpp:116 qalculatevariablesdialog.cpp:117 +#: qalculatevariablesdialog.cpp:183 qalculatevariablesdialog.cpp:462 +msgid "All" +msgstr "Alla" + +#: qalculateconvertunitsdialog.cpp:132 qalculateconvertunitsdialog.cpp:133 +#: qalculateconvertunitsdialog.cpp:134 qalculateconvertunitsdialog.cpp:182 +#: qalculatefunctionsdialog.cpp:165 qalculatefunctionsdialog.cpp:166 +#: qalculatefunctionsdialog.cpp:167 qalculatefunctionsdialog.cpp:236 +#: qalculatefunctionsdialog.cpp:262 qalculatefunctionsdialog.cpp:285 +#: qalculatefunctionsdialog.cpp:507 qalculateunitsdialog.cpp:197 +#: qalculateunitsdialog.cpp:198 qalculateunitsdialog.cpp:199 +#: qalculateunitsdialog.cpp:273 qalculateunitsdialog.cpp:299 +#: qalculateunitsdialog.cpp:322 qalculateunitsdialog.cpp:418 +#: qalculatevariablesdialog.cpp:165 qalculatevariablesdialog.cpp:166 +#: qalculatevariablesdialog.cpp:167 qalculatevariablesdialog.cpp:258 +#: qalculatevariablesdialog.cpp:284 qalculatevariablesdialog.cpp:322 +#: qalculatevariablesdialog.cpp:464 +msgid "Uncategorized" +msgstr "Okategoriserade" + +#: qalculatedatasetsdialog.cpp:46 qalculateeditdatasetdialog.cpp:232 +msgid "Data Sets" +msgstr "Dataset" + +#: qalculatedatasetsdialog.cpp:61 +msgid "Data Sets:" +msgstr "Dataset:" + +#: qalculatedatasetsdialog.cpp:68 qalculatedatasetsdialog.cpp:91 +#: qalculateeditdatasetdialog.cpp:107 qalculateeditdatasetdialog.cpp:629 +#: qalculateeditfunctiondialog.cpp:133 qalculateeditfunctiondialog.cpp:492 +#: qalculateeditnamesdialog.cpp:64 qalculatefunctionsdialog.cpp:67 +#: qalculateunitsdialog.cpp:91 qalculatevariablesdialog.cpp:66 +msgid "New" +msgstr "Ny" + +#: qalculatedatasetsdialog.cpp:77 qalculateeditdatasetdialog.cpp:79 +#: qalculateeditdatasetdialog.cpp:456 qalculateeditfunctiondialog.cpp:98 +msgid "Description:" +msgstr "Beskrivning:" + +#: qalculatedatasetsdialog.cpp:84 +msgid "Objects:" +msgstr "Objekt:" + +#: qalculatedatasetsdialog.cpp:87 qalculateeditdatasetdialog.cpp:236 +#: qalculateeditfunctiondialog.cpp:598 +msgid "Object" +msgstr "Objekt" + +#: qalculatedatasetsdialog.cpp:100 +msgid "Attributes:" +msgstr "Attribut:" + +#: qalculatedatasetsdialog.cpp:157 qalculatedatasetsdialog.cpp:218 +msgid "Data set does not exist anymore." +msgstr "Datasetet existerar inte längre." + +#: qalculatedatasetsdialog.cpp:300 qalculateeditdatasetdialog.cpp:195 +#: qalculatefunctionsdialog.cpp:456 +msgid "key" +msgstr "nyckel" + +#: qalculatedatasetsdialog.cpp:316 +msgid "Data Retrieval Function" +msgstr "Dataåtkomstfunktion" + +#: qalculatedecimalsdialog.cpp:31 +msgid "Max decimals:" +msgstr "Max decimaler:" + +#: qalculatedecimalsdialog.cpp:39 +msgid "Min decimals:" +msgstr "Min decimaler:" + +#: qalculateeditdataobjectdialog.cpp:30 qalculateeditdataobjectdialog.cpp:40 +msgid "Edit Object" +msgstr "Redigera objekt" + +#: qalculateeditdataobjectdialog.cpp:42 +msgid "New Object" +msgstr "Nytt objekt" + +#: qalculateeditdataobjectdialog.cpp:48 qalculateeditdatasetdialog.cpp:242 +msgid "Property" +msgstr "Egenskap" + +#. i18n: file ./qalculate_kdeui.rc line 116 +#: qalculateeditdataobjectdialog.cpp:51 rc.cpp:39 +#, no-c-format +msgid "Approximation" +msgstr "Approximering" + +#: qalculateeditdatasetdialog.cpp:53 qalculateeditdatasetdialog.cpp:307 +msgid "Edit Data Set" +msgstr "Redigera dataset" + +#: qalculateeditdatasetdialog.cpp:68 qalculateeditfunctiondialog.cpp:70 +#: qalculatepreferencesdialog.cpp:157 +msgid "General" +msgstr "Allmänt" + +#: qalculateeditdatasetdialog.cpp:73 qalculateplotdialog.cpp:86 +#: qalculateplotdialog.cpp:189 +msgid "Title:" +msgstr "Titel:" + +#: qalculateeditdatasetdialog.cpp:76 +msgid "Data file:" +msgstr "Datafil:" + +#: qalculateeditdatasetdialog.cpp:87 +msgid "Copyright:" +msgstr "Upphovsrätt:" + +#: qalculateeditdatasetdialog.cpp:97 +msgid "Properties:" +msgstr "Egenskaper:" + +#: qalculateeditdatasetdialog.cpp:99 qalculateplotdialog.cpp:153 +msgid "Title" +msgstr "Titel" + +#: qalculateeditdatasetdialog.cpp:100 qalculateeditdatasetdialog.cpp:620 +#: qalculateeditfunctiondialog.cpp:124 qalculateeditnamesdialog.cpp:41 +#: qalculateeditunitdialog.cpp:50 +msgid "Name" +msgstr "Namn" + +#: qalculateeditdatasetdialog.cpp:101 qalculateeditfunctiondialog.cpp:125 +#: qalculateeditunitdialog.cpp:75 qalculateeditunknownvariabledialog.cpp:60 +msgid "Type" +msgstr "Typ" + +#: qalculateeditdatasetdialog.cpp:115 qalculateeditdatasetdialog.cpp:442 +#: qalculateeditfunctiondialog.cpp:74 qalculateeditfunctiondialog.cpp:583 +#: qalculateeditmatrixvectordialog.cpp:78 qalculateeditunitdialog.cpp:55 +#: qalculateeditunknownvariabledialog.cpp:47 +#: qalculateeditvariabledialog.cpp:49 qalculateimportcsvdialog.cpp:60 +msgid "Name:" +msgstr "Namn:" + +#: qalculateeditdatasetdialog.cpp:124 qalculateeditdatasetdialog.cpp:451 +#: qalculateeditfunctiondialog.cpp:83 qalculateeditmatrixvectordialog.cpp:87 +#: qalculateeditunitdialog.cpp:64 qalculateeditunknownvariabledialog.cpp:56 +#: qalculateeditvariabledialog.cpp:60 +msgid "Names Details" +msgstr "Namndetaljer" + +#: qalculateeditdatasetdialog.cpp:126 +msgid "Object argument name:" +msgstr "Objektparameterns namn" + +#: qalculateeditdatasetdialog.cpp:129 +msgid "Property argument name:" +msgstr "Egenskapsparameterns namn:" + +#: qalculateeditdatasetdialog.cpp:132 +msgid "Default property:" +msgstr "Förvald egenskap:" + +#: qalculateeditdatasetdialog.cpp:173 +msgid "text" +msgstr "text" + +#: qalculateeditdatasetdialog.cpp:178 qalculateeditdatasetdialog.cpp:186 +msgid "approximate" +msgstr "approximerat" + +#: qalculateeditdatasetdialog.cpp:181 qalculateexpressionedit.cpp:712 +#: qalculatevariablesdialog.cpp:428 +msgid "number" +msgstr "nummer" + +#: qalculateeditdatasetdialog.cpp:189 +msgid "expression" +msgstr "uttryck" + +#: qalculateeditdatasetdialog.cpp:213 qalculateeditdatasetdialog.cpp:499 +#: qalculateeditfunctiondialog.cpp:190 qalculateeditmatrixvectordialog.cpp:185 +#: qalculateeditunitdialog.cpp:146 qalculateeditunknownvariabledialog.cpp:132 +#: qalculateeditvariabledialog.cpp:102 +msgid "Empty name field" +msgstr "Tomt namnfält" + +#: qalculateeditdatasetdialog.cpp:217 qalculateeditfunctiondialog.cpp:201 +msgid "" +"A function with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" +"En funktion med samma namn finns redan.\n" +"Vill du ersätta den?" + +#: qalculateeditdatasetdialog.cpp:309 +msgid "Edit Data Set (global)" +msgstr "Redigera dataset (systemvitt)" + +#: qalculateeditdatasetdialog.cpp:311 +msgid "New Data Set" +msgstr "Nytt dataset" + +#: qalculateeditdatasetdialog.cpp:322 +msgid "info" +msgstr "info" + +#: qalculateeditdatasetdialog.cpp:435 qalculateeditdatasetdialog.cpp:548 +msgid "Edit Property" +msgstr "Redigera egneskap" + +#: qalculateeditdatasetdialog.cpp:453 qalculateeditfunctiondialog.cpp:90 +#: qalculateeditmatrixvectordialog.cpp:93 qalculateeditunitdialog.cpp:66 +#: qalculateeditunknownvariabledialog.cpp:90 +#: qalculateeditvariabledialog.cpp:80 qalculateimportcsvdialog.cpp:63 +msgid "Descriptive name:" +msgstr "Beskrivande namn:" + +#: qalculateeditdatasetdialog.cpp:464 +msgid "Value type:" +msgstr "Värdetyp:" + +#: qalculateeditdatasetdialog.cpp:467 qalculateeditfunctiondialog.cpp:593 +msgid "Text" +msgstr "Text" + +#: qalculateeditdatasetdialog.cpp:469 qalculateeditfunctiondialog.cpp:482 +#: qalculateplotdialog.cpp:154 +msgid "Expression" +msgstr "Uttryck" + +#: qalculateeditdatasetdialog.cpp:474 +msgid "Use as key" +msgstr "Använd som nyckel" + +#: qalculateeditdatasetdialog.cpp:476 +msgid "Approximate value" +msgstr "Approximerat värde" + +#: qalculateeditdatasetdialog.cpp:478 +msgid "Case sensitive value" +msgstr "Storlekskänsligt värde" + +#: qalculateeditdatasetdialog.cpp:480 +msgid "Value uses brackets" +msgstr "Värdet användar klammrar" + +#: qalculateeditdatasetdialog.cpp:550 +msgid "New Property" +msgstr "Ny egenskap" + +#: qalculateeditdatasetdialog.cpp:615 qalculateeditnamesdialog.cpp:34 +msgid "Edit Names" +msgstr "Redigera namn" + +#: qalculateeditdatasetdialog.cpp:621 qalculateeditfunctiondialog.cpp:481 +#: qalculateeditnamesdialog.cpp:46 +msgid "Reference" +msgstr "Referens" + +#: qalculateeditfunctiondialog.cpp:55 qalculateeditfunctiondialog.cpp:286 +msgid "Edit Function" +msgstr "Redigera funktion" + +#: qalculateeditfunctiondialog.cpp:85 qalculateeditmatrixvectordialog.cpp:89 +#: qalculateeditunitdialog.cpp:87 qalculateeditunknownvariabledialog.cpp:85 +#: qalculateeditvariabledialog.cpp:74 qalculateimportcsvdialog.cpp:66 +msgid "Category:" +msgstr "Kategori:" + +#: qalculateeditfunctiondialog.cpp:96 +msgid "Hide function" +msgstr "Göm funktionen" + +#: qalculateeditfunctiondialog.cpp:106 qalculateplotdialog.cpp:89 +msgid "Expression:" +msgstr "Uttryck:" + +#: qalculateeditfunctiondialog.cpp:115 +msgid "Condition:" +msgstr "Villkor:" + +#: qalculateeditfunctiondialog.cpp:120 qalculateeditfunctiondialog.cpp:476 +msgid "Sub-Functions" +msgstr "Subfunktioner" + +#: qalculateeditfunctiondialog.cpp:122 +msgid "Arguments:" +msgstr "Parametrar:" + +#: qalculateeditfunctiondialog.cpp:197 +msgid "Empty expression field" +msgstr "Tomt uttrycksfält" + +#: qalculateeditfunctiondialog.cpp:288 +msgid "Edit Function (global)" +msgstr "Redigera funktion (systemvid)" + +#: qalculateeditfunctiondialog.cpp:290 +msgid "New Function" +msgstr "Ny funktion" + +#: qalculateeditfunctiondialog.cpp:483 +msgid "Precalculate" +msgstr "Förberäkna" + +#: qalculateeditfunctiondialog.cpp:579 qalculateeditfunctiondialog.cpp:675 +msgid "Edit Argument" +msgstr "Redigera parameter" + +#: qalculateeditfunctiondialog.cpp:586 +msgid "Type:" +msgstr "Typ:" + +#: qalculateeditfunctiondialog.cpp:589 +msgid "Free" +msgstr "Fri" + +#: qalculateeditfunctiondialog.cpp:592 +msgid "Symbol" +msgstr "Symbol" + +#: qalculateeditfunctiondialog.cpp:594 qalculateinsertfunctiondialog.cpp:353 +msgid "Date" +msgstr "Datum" + +#: qalculateeditfunctiondialog.cpp:597 +msgid "Boolean" +msgstr "Boolskt värde" + +#: qalculateeditfunctiondialog.cpp:603 +msgid "Angle" +msgstr "Vinkel" + +#: qalculateeditfunctiondialog.cpp:605 +msgid "Enable rules and type test" +msgstr "Aktivera villkors- och typtest" + +#: qalculateeditfunctiondialog.cpp:607 +msgid "Custom condition:" +msgstr "Anpassat villkor:" + +#: qalculateeditfunctiondialog.cpp:611 +msgid "Allow matrix" +msgstr "Tillåt matris" + +#: qalculateeditfunctiondialog.cpp:613 +msgid "Forbid zero" +msgstr "Förbjud noll" + +#: qalculateeditfunctiondialog.cpp:615 +msgid "Allow complex" +msgstr "Tillåt komplext" + +#: qalculateeditfunctiondialog.cpp:617 qalculateplotdialog.cpp:164 +msgid "Min:" +msgstr "Min:" + +#: qalculateeditfunctiondialog.cpp:624 qalculateeditfunctiondialog.cpp:633 +msgid "Include equals" +msgstr "Inkludera lika med" + +#: qalculateeditfunctiondialog.cpp:626 qalculateplotdialog.cpp:167 +msgid "Max:" +msgstr "Max:" + +#: qalculateeditfunctiondialog.cpp:677 +msgid "New Argument" +msgstr "Ny parameter" + +#: qalculateeditmatrixvectordialog.cpp:71 +#: qalculateeditunknownvariabledialog.cpp:40 +#: qalculateeditvariabledialog.cpp:41 qalculateeditvariabledialog.cpp:180 +#: qalculateinsertmatrixvectordialog.cpp:71 +msgid "Edit Variable" +msgstr "Redigera variabel" + +#: qalculateeditmatrixvectordialog.cpp:96 +#: qalculateinsertmatrixvectordialog.cpp:75 +msgid "Rows:" +msgstr "Rader:" + +#: qalculateeditmatrixvectordialog.cpp:99 +#: qalculateinsertmatrixvectordialog.cpp:78 +msgid "Columns:" +msgstr "Kolumner:" + +#: qalculateeditmatrixvectordialog.cpp:112 +#: qalculateeditmatrixvectordialog.cpp:133 +#: qalculateeditmatrixvectordialog.cpp:295 +#: qalculateinsertmatrixvectordialog.cpp:91 +#: qalculateinsertmatrixvectordialog.cpp:115 +#: qalculateinsertmatrixvectordialog.cpp:275 +msgid "Elements:" +msgstr "Element:" + +#: qalculateeditmatrixvectordialog.cpp:146 +#: qalculateeditmatrixvectordialog.cpp:292 +#: qalculateinsertmatrixvectordialog.cpp:128 +#: qalculateinsertmatrixvectordialog.cpp:272 +msgid "Elements (in horizontal order):" +msgstr "Element (radvis)" + +#: qalculateeditmatrixvectordialog.cpp:189 +#: qalculateeditunknownvariabledialog.cpp:136 +#: qalculateeditvariabledialog.cpp:114 +msgid "" +"An unit or variable with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" +"En enhet eller variabel med samma namn finns redan.\n" +"Vill du ersätta den?" + +#: qalculateeditmatrixvectordialog.cpp:301 +msgid "Edit Vector" +msgstr "Redigera vektor" + +#: qalculateeditmatrixvectordialog.cpp:303 +msgid "Edit Vector (global)" +msgstr "Redigera vektor (systemvid)" + +#: qalculateeditmatrixvectordialog.cpp:305 +msgid "New Vector" +msgstr "Ny vektor" + +#: qalculateeditmatrixvectordialog.cpp:310 +msgid "Edit Matrix" +msgstr "Redigera matris" + +#: qalculateeditmatrixvectordialog.cpp:312 +msgid "Edit Matrix (global)" +msgstr "Redigera matris (systemvid)" + +#: qalculateeditmatrixvectordialog.cpp:314 +msgid "New Matrix" +msgstr "Ny matris" + +#: qalculateeditnamesdialog.cpp:42 +msgid "Abbreviation" +msgstr "Förkortning" + +#: qalculateeditnamesdialog.cpp:44 +msgid "Plural" +msgstr "Plural" + +#: qalculateeditnamesdialog.cpp:48 +msgid "Avoid Input" +msgstr "Undvik input" + +#: qalculateeditnamesdialog.cpp:50 +msgid "Unicode" +msgstr "Unicode" + +#: qalculateeditnamesdialog.cpp:52 +msgid "Suffix" +msgstr "Suffix" + +#: qalculateeditnamesdialog.cpp:54 +msgid "Case Sensitive" +msgstr "Storlekskänslig" + +#: qalculateeditunitdialog.cpp:43 qalculateeditunitdialog.cpp:287 +msgid "Edit Unit" +msgstr "Redigera enhet" + +#: qalculateeditunitdialog.cpp:72 +msgid "Hide unit" +msgstr "Göm enheten" + +#: qalculateeditunitdialog.cpp:80 +msgid "Class:" +msgstr "Klass:" + +#: qalculateeditunitdialog.cpp:83 +msgid "Base Unit" +msgstr "Basenhet" + +#: qalculateeditunitdialog.cpp:84 +msgid "Alias" +msgstr "Alias" + +#: qalculateeditunitdialog.cpp:85 +msgid "Composite Unit" +msgstr "Sammansatt enhet" + +#: qalculateeditunitdialog.cpp:92 +msgid "System:" +msgstr "System:" + +#: qalculateeditunitdialog.cpp:95 +msgid "SI" +msgstr "SI" + +#: qalculateeditunitdialog.cpp:96 +msgid "CGS" +msgstr "CGS" + +#: qalculateeditunitdialog.cpp:97 +msgid "Imperial" +msgstr "Imperial" + +#: qalculateeditunitdialog.cpp:98 +msgid "US Survey" +msgstr "US Survey" + +#: qalculateeditunitdialog.cpp:102 +msgid "Relation" +msgstr "Relation" + +#: qalculateeditunitdialog.cpp:107 +msgid "Base unit:" +msgstr "Basenhet:" + +#: qalculateeditunitdialog.cpp:110 +msgid "Exponent:" +msgstr "Exponent:" + +#: qalculateeditunitdialog.cpp:114 +msgid "Relation:" +msgstr "Relation:" + +#: qalculateeditunitdialog.cpp:121 +msgid "Relation is exact" +msgstr "Relationen är exakt" + +#: qalculateeditunitdialog.cpp:123 +msgid "Inverse relation:" +msgstr "Omvänd relation:" + +#: qalculateeditunitdialog.cpp:150 +msgid "" +"A variable or unit with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" +"En variabel eller enhet med samma namn finns redan.\n" +"Vill du ersätta den?" + +#: qalculateeditunitdialog.cpp:175 qalculateeditunitdialog.cpp:219 +msgid "Base unit does not exist" +msgstr "Basenheten finns inte" + +#: qalculateeditunitdialog.cpp:289 +msgid "Edit Unit (global)" +msgstr "Redigera enhet (systemvid)" + +#: qalculateeditunitdialog.cpp:291 +msgid "New Unit" +msgstr "Ny enhet" + +#: qalculateeditunknownvariabledialog.cpp:58 +msgid "Custom assumptions:" +msgstr "Anpassade antaganden:" + +#: qalculateeditunknownvariabledialog.cpp:68 +msgid "Complex Number" +msgstr "Komplext nummer" + +#: qalculateeditunknownvariabledialog.cpp:69 +msgid "Real Number" +msgstr "Reellt tal" + +#: qalculateeditunknownvariabledialog.cpp:70 +msgid "Rational Number" +msgstr "Rationellt tal" + +#: qalculateeditunknownvariabledialog.cpp:73 +msgid "Sign" +msgstr "Tecken" + +#: qalculateeditunknownvariabledialog.cpp:199 +msgid "Edit Unknown Variable" +msgstr "Redigera okänd variabel" + +#: qalculateeditunknownvariabledialog.cpp:201 +msgid "Edit Unknown Variable (global)" +msgstr "Redigera okänd variabel (systemvid)" + +#: qalculateeditunknownvariabledialog.cpp:203 +msgid "New Unknown Variable" +msgstr "Ny okänd variabel" + +#: qalculateeditvariabledialog.cpp:63 qalculateinsertfunctiondialog.cpp:91 +msgid "Value:" +msgstr "Värde:" + +#: qalculateeditvariabledialog.cpp:71 +msgid "Value is exact" +msgstr "Värdet är exakt" + +#: qalculateeditvariabledialog.cpp:110 +msgid "Empty value field" +msgstr "Tomt värdefält" + +#: qalculateeditvariabledialog.cpp:182 +msgid "Edit Variable (global)" +msgstr "Redigera variabel (systemvid)" + +#: qalculateeditvariabledialog.cpp:185 +msgid "New Variable" +msgstr "Ny variabel" + +#: qalculateexportcsvdialog.cpp:37 qalculateexportcsvdialog.cpp:54 +msgid "Export CSV File" +msgstr "Exportera CSV-fil" + +#: qalculateexportcsvdialog.cpp:42 +msgid "Current result" +msgstr "Nuvarande resultat" + +#: qalculateexportcsvdialog.cpp:46 +msgid "Matrix/vector variable" +msgstr "Matris/vektorvariabel" + +#: qalculateexportcsvdialog.cpp:51 qalculateimportcsvdialog.cpp:43 +msgid "File:" +msgstr "Fil:" + +#: qalculateexportcsvdialog.cpp:56 qalculateimportcsvdialog.cpp:80 +msgid "Delimiter:" +msgstr "Avgränsare:" + +#: qalculateexportcsvdialog.cpp:59 qalculateimportcsvdialog.cpp:83 +msgid "Comma" +msgstr "Komma" + +#: qalculateexportcsvdialog.cpp:60 qalculateimportcsvdialog.cpp:84 +msgid "Tabulator" +msgstr "Tabulator" + +#: qalculateexportcsvdialog.cpp:61 qalculateimportcsvdialog.cpp:85 +msgid "Semicolon" +msgstr "Semikolon" + +#: qalculateexportcsvdialog.cpp:62 qalculateimportcsvdialog.cpp:86 +msgid "Space" +msgstr "Mellanslag" + +#: qalculateexportcsvdialog.cpp:63 qalculateimportcsvdialog.cpp:87 +msgid "Other" +msgstr "Annan" + +#: qalculateexportcsvdialog.cpp:93 qalculateimportcsvdialog.cpp:116 +msgid "No file name entered." +msgstr "Inget filnamn angivet." + +#: qalculateexportcsvdialog.cpp:122 qalculateimportcsvdialog.cpp:145 +msgid "No delimiter selected." +msgstr "Ingen avgränsare vald." + +#: qalculateexportcsvdialog.cpp:135 +msgid "No variable name entered." +msgstr "Inget variabelnamn angivet." + +#: qalculateexportcsvdialog.cpp:147 +msgid "No known variable with entered name found." +msgstr "Det finns ingen känd variabel med angivet namn." + +#: qalculateexportcsvdialog.cpp:154 +#, c-format +msgid "" +"Could not export to file \n" +"%s" +msgstr "" +"Kunde inte exportera till \n" +"%s" + +#: qalculateexpressionedit.cpp:146 +msgid "Disable Completion" +msgstr "Avaktivera komplettering" + +#: qalculateexpressionedit.cpp:147 +msgid "Enable Completion" +msgstr "Aktivera komplettering" + +#. i18n: file ./qalculate_kdeui.rc line 154 +#: qalculateexpressionedit.cpp:161 qalculateresultdisplay.cpp:333 rc.cpp:48 +#, no-c-format +msgid "Meta Modes" +msgstr "Metalägen" + +#: qalculateexpressionedit.cpp:655 qalculatevariablesdialog.cpp:366 +msgid "a previous result" +msgstr "ett tidigare resultat" + +#: qalculateexpressionedit.cpp:661 qalculatevariablesdialog.cpp:376 +msgid "matrix" +msgstr "matris" + +#: qalculateexpressionedit.cpp:663 qalculatevariablesdialog.cpp:378 +msgid "vector" +msgstr "vektor" + +#: qalculateexpressionedit.cpp:672 qalculatevariablesdialog.cpp:387 +msgid "positive" +msgstr "positivt" + +#: qalculateexpressionedit.cpp:676 qalculatevariablesdialog.cpp:391 +msgid "non-positive" +msgstr "ej positivt" + +#: qalculateexpressionedit.cpp:680 qalculatevariablesdialog.cpp:395 +msgid "negative" +msgstr "negativt" + +#: qalculateexpressionedit.cpp:684 qalculatevariablesdialog.cpp:399 +msgid "non-negative" +msgstr "ej negativt" + +#: qalculateexpressionedit.cpp:688 qalculatevariablesdialog.cpp:403 +msgid "non-zero" +msgstr "ej noll" + +#: qalculateexpressionedit.cpp:696 qalculatevariablesdialog.cpp:412 +msgid "integer" +msgstr "heltal" + +#: qalculateexpressionedit.cpp:700 qalculatevariablesdialog.cpp:416 +msgid "rational" +msgstr "rationell" + +#: qalculateexpressionedit.cpp:704 qalculatevariablesdialog.cpp:420 +msgid "real" +msgstr "reell" + +#: qalculateexpressionedit.cpp:708 qalculatevariablesdialog.cpp:424 +msgid "complex" +msgstr "komplex" + +#: qalculateexpressionedit.cpp:716 qalculatevariablesdialog.cpp:432 +msgid "(not matrix)" +msgstr "(inte matris)" + +#: qalculateexpressionedit.cpp:721 qalculatevariablesdialog.cpp:438 +msgid "unknown" +msgstr "okänd" + +#: qalculateexpressionedit.cpp:723 qalculatevariablesdialog.cpp:440 +msgid "default assumptions" +msgstr "förvalda antaganden" + +#: qalculatefunctionsdialog.cpp:47 +msgid "Functions" +msgstr "Funktioner" + +#: qalculatefunctionsdialog.cpp:59 +msgid "Function Name" +msgstr "Funktionsnamn" + +#: qalculatefunctionsdialog.cpp:75 qalculatefunctionsdialog.cpp:313 +#: qalculateunitsdialog.cpp:99 qalculateunitsdialog.cpp:352 +#: qalculatevariablesdialog.cpp:74 qalculatevariablesdialog.cpp:349 +msgid "Deactivate" +msgstr "Avaktivera" + +#: qalculatefunctionsdialog.cpp:174 qalculatefunctionsdialog.cpp:175 +#: qalculatefunctionsdialog.cpp:176 qalculatefunctionsdialog.cpp:234 +#: qalculatefunctionsdialog.cpp:260 qalculatefunctionsdialog.cpp:283 +#: qalculatefunctionsdialog.cpp:509 qalculateunitsdialog.cpp:206 +#: qalculateunitsdialog.cpp:207 qalculateunitsdialog.cpp:208 +#: qalculateunitsdialog.cpp:271 qalculateunitsdialog.cpp:297 +#: qalculateunitsdialog.cpp:320 qalculateunitsdialog.cpp:420 +#: qalculatevariablesdialog.cpp:174 qalculatevariablesdialog.cpp:175 +#: qalculatevariablesdialog.cpp:176 qalculatevariablesdialog.cpp:256 +#: qalculatevariablesdialog.cpp:282 qalculatevariablesdialog.cpp:320 +#: qalculatevariablesdialog.cpp:466 +msgid "Inactive" +msgstr "Avaktiverade" + +#: qalculatefunctionsdialog.cpp:315 qalculateunitsdialog.cpp:354 +#: qalculatevariablesdialog.cpp:351 +msgid "Activate" +msgstr "Aktivera" + +#: qalculatefunctionsdialog.cpp:367 qalculateresultdisplay.cpp:148 +#, c-format +msgid "" +"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." +msgstr "" +"Inhämtar data från \"%s\" datasetet för ett givet objekt och egenskap. Om " +"\"info\" anges som egenskap, visas ett fönster med alla egenskaper för " +"objektet." + +#: qalculatefunctionsdialog.cpp:391 +msgid "Arguments" +msgstr "Parametrar" + +#: qalculatefunctionsdialog.cpp:412 qalculateinsertfunctiondialog.cpp:194 +#: qalculateinsertfunctiondialog.cpp:227 +msgid "optional" +msgstr "frivillig" + +#: qalculatefunctionsdialog.cpp:416 +msgid "default: " +msgstr "förvald:" + +#: qalculatefunctionsdialog.cpp:426 +msgid "Requirement" +msgstr "Krav" + +#: qalculateimportcsvdialog.cpp:39 qalculateimportcsvdialog.cpp:46 +msgid "Import CSV File" +msgstr "Importera CSV-fil" + +#: qalculateimportcsvdialog.cpp:48 +msgid "Import as:" +msgstr "Importera som:" + +#: qalculateimportcsvdialog.cpp:71 +msgid "First row:" +msgstr "Första raden:" + +#: qalculateimportcsvdialog.cpp:77 +msgid "Includes headings" +msgstr "Inkluderar kolumnnamn" + +#: qalculateimportcsvdialog.cpp:149 +msgid "An error occured when importing the CSV file." +msgstr "Ett fel uppstod vid import av CSV-fil." + +#: qalculateinsertfunctiondialog.cpp:50 qalculateinsertfunctiondialog.cpp:57 +msgid "Execute" +msgstr "Exekvera" + +#: qalculateinsertfunctiondialog.cpp:93 +msgid "Argument" +msgstr "Parameter" + +#: qalculateinsertfunctiondialog.cpp:152 +msgid "True" +msgstr "Sant" + +#: qalculateinsertfunctiondialog.cpp:153 +msgid "False" +msgstr "Falskt" + +#: qalculateinsertfunctiondialog.cpp:184 +msgid "Info" +msgstr "Info" + +#: qalculateinsertmatrixvectordialog.cpp:71 +msgid "Insert Selection" +msgstr "Infoga markering" + +#: qalculateinsertmatrixvectordialog.cpp:293 +msgid "Vector Result" +msgstr "Vektorresultat" + +#: qalculateinsertmatrixvectordialog.cpp:295 +msgid "Matrix Result" +msgstr "Matrisresultat" + +#: qalculateperiodictabledialog.cpp:195 +msgid "Element Data" +msgstr "Elementdata" + +#: qalculateperiodictabledialog.cpp:221 +msgid "Classification" +msgstr "Klassificering" + +#: qalculateperiodictabledialog.cpp:224 +msgid "Alkali Metal" +msgstr "Alkalimetall" + +#: qalculateperiodictabledialog.cpp:225 +msgid "Alkaline-Earth Metal" +msgstr "Jordalkalimetall" + +#: qalculateperiodictabledialog.cpp:226 +msgid "Lanthanide" +msgstr "Lantanid" + +#: qalculateperiodictabledialog.cpp:227 +msgid "Actinide" +msgstr "Aktinid" + +#: qalculateperiodictabledialog.cpp:228 +msgid "Transition Metal" +msgstr "Övergångsmetall" + +#: qalculateperiodictabledialog.cpp:229 +msgid "Metal" +msgstr "Metall" + +#: qalculateperiodictabledialog.cpp:230 +msgid "Metalloid" +msgstr "Halvmetall" + +#: qalculateperiodictabledialog.cpp:231 +msgid "Non-Metal" +msgstr "Icke-metall" + +#: qalculateperiodictabledialog.cpp:232 +msgid "Halogen" +msgstr "" + +#: qalculateperiodictabledialog.cpp:233 +msgid "Noble Gas" +msgstr "Ädelgas" + +#: qalculateperiodictabledialog.cpp:234 +msgid "Transactinide" +msgstr "Transaktinid" + +#: qalculateplotdialog.cpp:64 +msgid "Plot" +msgstr "Diagram" + +#: qalculateplotdialog.cpp:82 +msgid "Data" +msgstr "Data" + +#: qalculateplotdialog.cpp:83 +msgid "Function Range" +msgstr "Funktionsomfång" + +#: qalculateplotdialog.cpp:101 +msgid "Vector/matrix" +msgstr "Vektor/matris" + +#: qalculateplotdialog.cpp:104 +msgid "Paired matrix" +msgstr "Parvis matris" + +#: qalculateplotdialog.cpp:107 +msgid "Rows" +msgstr "Rader" + +#: qalculateplotdialog.cpp:109 +msgid "X variable:" +msgstr "X-variabel" + +#: qalculateplotdialog.cpp:113 +msgid "Style:" +msgstr "Stil:" + +#: qalculateplotdialog.cpp:115 +msgid "Line" +msgstr "Kurva" + +#: qalculateplotdialog.cpp:116 +msgid "Points" +msgstr "Punkter" + +#: qalculateplotdialog.cpp:117 +msgid "Line with points" +msgstr "Kurva med punkter" + +#: qalculateplotdialog.cpp:118 +msgid "Boxes/bars" +msgstr "Boxar/staplar" + +#: qalculateplotdialog.cpp:119 +msgid "Histogram" +msgstr "Histogram" + +#: qalculateplotdialog.cpp:120 +msgid "Steps" +msgstr "Steg" + +#: qalculateplotdialog.cpp:121 +msgid "Candlesticks" +msgstr "Ljusstakar" + +#: qalculateplotdialog.cpp:122 +msgid "Dots" +msgstr "Små punkter" + +#: qalculateplotdialog.cpp:124 +msgid "Smoothing:" +msgstr "Utjämning:" + +#: qalculateplotdialog.cpp:127 +msgid "Monotonic" +msgstr "Monoton" + +#: qalculateplotdialog.cpp:128 +msgid "Natural cubic splines" +msgstr "" + +#: qalculateplotdialog.cpp:129 +msgid "Bezier" +msgstr "" + +#: qalculateplotdialog.cpp:130 +msgid "Bezier (monotonic)" +msgstr "Bezier (monoton)" + +#: qalculateplotdialog.cpp:132 +msgid "Y-axis:" +msgstr "Y-axel:" + +#: qalculateplotdialog.cpp:136 +msgid "Primary" +msgstr "Primär" + +#: qalculateplotdialog.cpp:139 +msgid "Secondary" +msgstr "Sekundär" + +#: qalculateplotdialog.cpp:171 +msgid "Sampling rate:" +msgstr "Frekvens:" + +#: qalculateplotdialog.cpp:176 +msgid "Step size:" +msgstr "Stegstorlek:" + +#: qalculateplotdialog.cpp:194 +msgid "Display grid" +msgstr "Visa rutnät" + +#: qalculateplotdialog.cpp:196 +msgid "Display full border" +msgstr "Visa helram" + +#: qalculateplotdialog.cpp:199 +msgid "Logarithmic x scale:" +msgstr "Logaritmisk x-skala:" + +#: qalculateplotdialog.cpp:203 +msgid "Logarithmic y scale:" +msgstr "Logaritmisk y-skala:" + +#: qalculateplotdialog.cpp:207 +msgid "X-axis label:" +msgstr "Namn på x-axeln:" + +#: qalculateplotdialog.cpp:210 +msgid "Y-axis label:" +msgstr "Namn på y-axeln:" + +#: qalculateplotdialog.cpp:213 +msgid "Color display:" +msgstr "Färgvisning:" + +#: qalculateplotdialog.cpp:217 +msgid "Color" +msgstr "Färg" + +#: qalculateplotdialog.cpp:220 +msgid "Monochrome" +msgstr "Monokrom" + +#: qalculateplotdialog.cpp:224 +msgid "Legend placement:" +msgstr "Textplacering:" + +#: qalculateplotdialog.cpp:227 +msgid "Top-left" +msgstr "Uppe till vänster" + +#: qalculateplotdialog.cpp:228 +msgid "Top-right" +msgstr "Uppe till höger" + +#: qalculateplotdialog.cpp:229 +msgid "Bottom-left" +msgstr "Nere till vänster" + +#: qalculateplotdialog.cpp:230 +msgid "Bottom-right" +msgstr "Nere till höger" + +#: qalculateplotdialog.cpp:231 +msgid "Below" +msgstr "Under" + +#: qalculateplotdialog.cpp:232 +msgid "Outside" +msgstr "Utanför" + +#: qalculateplotdialog.cpp:403 qalculateplotdialog.cpp:458 +#: qalculateplotdialog.cpp:506 +msgid "Empty expression." +msgstr "Tomt uttryck." + +#: qalculateplotdialog.cpp:472 qalculateplotdialog.cpp:519 +msgid "Empty x variable." +msgstr "Tom x-variabel." + +#: qalculateprecisiondialog.cpp:34 qalculateprecisiondialog.cpp:36 +msgid "Recalculate" +msgstr "Omräkna" + +#: qalculateprecisiondialog.cpp:41 +msgid "Precision:" +msgstr "Precision:" + +#: qalculatepreferencesdialog.cpp:100 +msgid "Choose..." +msgstr "Välj..." + +#: qalculatepreferencesdialog.cpp:147 +msgid "Preferences" +msgstr "Inställningar" + +#: qalculatepreferencesdialog.cpp:161 +msgid "Close to system tray" +msgstr "Stäng till aktivitetsfältet" + +#: qalculatepreferencesdialog.cpp:162 +msgid "" +"If the application will reside in the system tray when the window is closed" +msgstr "" +"Om programmet skall befinna sig i aktivitetsfältet när fönstret är stängt" + +#: qalculatepreferencesdialog.cpp:164 +msgid "Display expression status" +msgstr "Visa uttrycksstatus." + +#: qalculatepreferencesdialog.cpp:165 +msgid "" +"If as-you-type expression status shall be displayed below the expression " +"entry" +msgstr "Om uttrycksstatus skall visas under uttrycksfältet medans text skrivs" + +#: qalculatepreferencesdialog.cpp:167 +msgid "Use icon buttons" +msgstr "Använd ikonknappar" + +#: qalculatepreferencesdialog.cpp:168 +msgid "" +"Use icons instead of text on the top-right buttons. The third state uses the " +"style setting for icons on buttons." +msgstr "" +"Använd ikoner istället för text på knapparna uppe till höger. Det tredje " +"läget använder stilinställningarna för ikoner på knappar." + +#: qalculatepreferencesdialog.cpp:171 +msgid "Update exchange rates on start" +msgstr "Uppdatera växelkurser vid start" + +#: qalculatepreferencesdialog.cpp:172 +msgid "" +"If current exchange rates shall be downloaded from the internet at program " +"start" +msgstr "" +"Huruvida uppdaterade växelkurser skall hämtas från intenet vid programstart" + +#: qalculatepreferencesdialog.cpp:174 +msgid "Save mode on exit" +msgstr "Spara läge vid avslut" + +#: qalculatepreferencesdialog.cpp:175 +msgid "If the mode of the calculator shall be restored" +msgstr "Huruvida kalkulatorns läge skall återskapas" + +#: qalculatepreferencesdialog.cpp:177 +msgid "Save definitions on exit" +msgstr "Spara definitioner vid avslut" + +#: qalculatepreferencesdialog.cpp:178 +msgid "" +"If changes to functions, units and variables shall be saved automatically" +msgstr "" +"Huruvida modifieringar av funktioner, enheter och variabler skall sparas " +"automatiskt" + +#: qalculatepreferencesdialog.cpp:180 +msgid "Use only keypad keys for RPN" +msgstr "Använd enbart knappsatstangenter för RPN" + +#: qalculatepreferencesdialog.cpp:181 +msgid "" +"Use only keypad keys for RPN operations (+-*/^) and use the rest of the " +"keyboard for expression entry" +msgstr "" +"Använd enbart knappsatstangenter för RPN operationer (+-*/^) och använd " +"resten av tangentbordet för att skriva uttryck" + +#: qalculatepreferencesdialog.cpp:183 +msgid "Ignores dots in numbers" +msgstr "Bortse från punkter nummer" + +#: qalculatepreferencesdialog.cpp:184 +msgid "" +"Allow dots, '.', to be used as thousands separator instead of as an " +"alternative to decimal sign" +msgstr "" +"Tillåt att punkter, '.', används som tusentalsseparator istället för som ett " +"alternativt decimaltecken" + +#: qalculatepreferencesdialog.cpp:187 +msgid "Enable unicode signs" +msgstr "Använd unicodetecken" + +#: qalculatepreferencesdialog.cpp:188 +msgid "Disable this if you have problems with some fancy characters" +msgstr "Avaktivera om du har problem med konstiga tecken" + +#: qalculatepreferencesdialog.cpp:190 +msgid "Use lower case in numbers" +msgstr "Använd små bokstäver i nummer" + +#: qalculatepreferencesdialog.cpp:191 +msgid "If lower case letters should be used in numbers with non-decimal base" +msgstr "Huruvida små bokstäver skall användas i nummer med icke-decimal bas" + +#: qalculatepreferencesdialog.cpp:193 +msgid "Use lower case \"e\"" +msgstr "Använd litet \"e\"" + +#: qalculatepreferencesdialog.cpp:194 +msgid "If \"e\"; shall be used instead of \"E\" in numbers" +msgstr "Om \"e\" skall anvädas istället för \"E\" i nummer" + +#: qalculatepreferencesdialog.cpp:196 +msgid "Alternative base prefixes" +msgstr "Alternativa basprefix" + +#: qalculatepreferencesdialog.cpp:197 +msgid "" +"If hexadecimal numbers shall be displayed with \"0x0\" and binary numbers " +"with \"0b00\" as prefixes" +msgstr "" +"Om hexadecimala tal ska visas med \"0x0\" och binära tal med \"0b00\" som " +"prefix" + +#: qalculatepreferencesdialog.cpp:199 +msgid "Spell out logical operators" +msgstr "Visa ord för logiska operatorer" + +#: qalculatepreferencesdialog.cpp:200 +msgid "If logical and/or shall be displayed as \"&&\"/\"||\" or \"and\"/\"or\"" +msgstr "" +"Om logiskt och/eller ska visas som \"&&\"/\"||\" eller \"och\"/\"eller\" " + +#: qalculatepreferencesdialog.cpp:203 +msgid "Multiplication sign:" +msgstr "Multiplikationstecken:" + +#: qalculatepreferencesdialog.cpp:215 +msgid "Division sign:" +msgstr "Divisionstecken:" + +#: qalculatepreferencesdialog.cpp:230 +msgid "Custom result font" +msgstr "Anpassat teckensnitt för resultat" + +#: qalculatepreferencesdialog.cpp:234 +msgid "Custom expression font" +msgstr "Anpassat teckensnitt för uttryck" + +#: qalculatepreferencesdialog.cpp:238 +msgid "Custom status font" +msgstr "Anpassat teckensnitt för status" + +#: qalculatepreferencesdialog.cpp:243 +msgid "Status error color:" +msgstr "Statusfelsfärg" + +#: qalculatepreferencesdialog.cpp:250 +msgid "Status warning color:" +msgstr "Statusvarningsfärg" + +#: qalculateresultdisplay.cpp:52 +msgid "a matrix" +msgstr "en matris" + +#: qalculateresultdisplay.cpp:54 +msgid "a vector" +msgstr "en vektor" + +#: qalculateresultdisplay.cpp:57 +msgid "double-click to view/edit" +msgstr "dubbelkicka för att visa/redigera" + +#: qalculateresultdisplay.cpp:60 +msgid "Unknown variable" +msgstr "Okänd variabel" + +#: qalculateresultdisplay.cpp:72 +msgid "Prefix" +msgstr "Prefix" + +#: qalculateresultdisplay.cpp:336 +msgid "Show Parsed Expression" +msgstr "Visa uttryckstolkning" + +#: qalculateresultdisplay.cpp:342 qalculateresultdisplay.cpp:353 +msgid "Show Object Info" +msgstr "Visa objektinfo" + +#: qalculateresultdisplay.cpp:348 +msgid "View/Edit Matrix" +msgstr "Visa/redigera matris" + +#: qalculateresultdisplay.cpp:350 +msgid "View/Edit Vector" +msgstr "Visa/redigera vektor" + +#: qalculateresultdisplay.cpp:382 +msgid "Parsed expression:" +msgstr "Tolkat uttryck:" + +#: qalculatesetbasedialog.cpp:33 +msgid "Result Base" +msgstr "Resultatbas" + +#: qalculatesetbasedialog.cpp:39 qalculatesetbasedialog.cpp:52 +msgid "Other:" +msgstr "Annan:" + +#: qalculatesetbasedialog.cpp:43 +msgid "Time format" +msgstr "Tidsformat" + +#: qalculatesetbasedialog.cpp:44 qalculatesetbasedialog.cpp:55 +msgid "Roman numerals" +msgstr "Romerska siffror" + +#: qalculatesetbasedialog.cpp:46 +msgid "Expression Base" +msgstr "Uttrycksbas" + +#: qalculateunitsdialog.cpp:54 +msgid "Units" +msgstr "Enheter" + +#: qalculateunitsdialog.cpp:68 +msgid "Names" +msgstr "Namn" + +#: qalculateunitsdialog.cpp:69 +msgid "Base" +msgstr "Bas" + +#: qalculateunitsdialog.cpp:72 +msgid "Conversion" +msgstr "Omvandling" + +#: qalculateunitsdialog.cpp:105 +msgid "Convert Result" +msgstr "Omvandla resultat" + +#: qalculateunitsdialog.cpp:250 +msgid "Cannot delete unit as it is needed by other units." +msgstr "Kan inte ta bort enheten eftersom den används av andra enheter." + +#: qalculatevariablesdialog.cpp:51 +msgid "Variables" +msgstr "Variabler" + +#: qalculatevariablesdialog.cpp:60 +msgid "Variable Name" +msgstr "Variabelnamn" + +#. i18n: file ./qalculate_kdeui.rc line 5 +#: rc.cpp:6 +#, no-c-format +msgid "&New" +msgstr "&Ny" + +#. i18n: file ./qalculate_kdeui.rc line 37 +#: rc.cpp:12 +#, no-c-format +msgid "&Set Prefix" +msgstr "&Välj prefix" + +#. i18n: file ./qalculate_kdeui.rc line 39 +#: rc.cpp:15 +#, no-c-format +msgid "&Convert To Unit" +msgstr "&Omvandla till enhet" + +#. i18n: file ./qalculate_kdeui.rc line 54 +#: rc.cpp:18 +#, no-c-format +msgid "&Mode" +msgstr "&Läge" + +#. i18n: file ./qalculate_kdeui.rc line 55 +#: rc.cpp:21 +#, no-c-format +msgid "Number Base" +msgstr "Nummerbas" + +#. i18n: file ./qalculate_kdeui.rc line 67 +#: rc.cpp:24 +#, no-c-format +msgid "Numerical Display" +msgstr "Numerisk visning" + +#. i18n: file ./qalculate_kdeui.rc line 80 +#: rc.cpp:27 +#, no-c-format +msgid "Fractional Display" +msgstr "Bråktalsvisning" + +#. i18n: file ./qalculate_kdeui.rc line 86 +#: rc.cpp:30 +#, no-c-format +msgid "Unit Display" +msgstr "Enhetsvisning" + +#. i18n: file ./qalculate_kdeui.rc line 96 +#: rc.cpp:33 +#, no-c-format +msgid "Angle Unit" +msgstr "Vinkelenhet" + +#. i18n: file ./qalculate_kdeui.rc line 104 +#: rc.cpp:36 +#, no-c-format +msgid "Enabled Objects" +msgstr "Aktiverade objekt" + +#. i18n: file ./qalculate_kdeui.rc line 121 +#: rc.cpp:42 +#, no-c-format +msgid "Assumptions" +msgstr "Antaganden" + +#. i18n: file ./qalculate_kdeui.rc line 137 +#: rc.cpp:45 +#, no-c-format +msgid "Algebraic Mode" +msgstr "Algebraiskt läge" + +#. i18n: file ./qalculate_kdeui.rc line 161 +#: rc.cpp:51 +#, no-c-format +msgid "Fu&nctions" +msgstr "Fu&nktioner" + +#. i18n: file ./qalculate_kdeui.rc line 163 +#: rc.cpp:54 +#, no-c-format +msgid "&Variables" +msgstr "&Variabler" + +#. i18n: file ./qalculate_kdeui.rc line 165 +#: rc.cpp:57 +#, no-c-format +msgid "&Units" +msgstr "&Enheter" diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100644 index 0000000..68db4e8 --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,2604 @@ +# translation of qalculate_kde.po to Simplified Chinese +# translation of qalculate_kde.po to +# This file is put in the public domain. +# +# Roy Qu , 2007. +# Roy Qu , 2007. +msgid "" +msgstr "" +"Project-Id-Version: qalculate_kde\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2006-11-05 10:12+0100\n" +"PO-Revision-Date: 2007-08-01 13:17+0800\n" +"Last-Translator: Roy Qu \n" +"Language-Team: Simplified Chinese\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.11.4\n" + +#: _translatorinfo.cpp:1 +msgid "" +"_: NAME OF TRANSLATORS\n" +"Your names" +msgstr "Roy Qu" + +#: _translatorinfo.cpp:3 +msgid "" +"_: EMAIL OF TRANSLATORS\n" +"Your emails" +msgstr "royqh1979@gmail.com" + +#: kqalculate.cpp:264 +msgid "Remove from System Tray" +msgstr "从系统托盘中移除" + +#: kqalculate.cpp:265 qalculateeditdatasetdialog.cpp:471 +#: qalculateplotdialog.cpp:226 +msgid "Hide" +msgstr "隐藏" + +#: kqalculate.cpp:286 kqalculate.cpp:4481 kqalculate.cpp:5912 +msgid "Enter" +msgstr "输入" + +#: kqalculate.cpp:287 kqalculate.cpp:513 kqalculate.cpp:4482 +#: kqalculate.cpp:4489 kqalculate.cpp:5913 +msgid "=" +msgstr "=" + +#: kqalculate.cpp:289 kqalculate.cpp:514 kqalculate.cpp:4486 +#: kqalculate.cpp:4487 +msgid "Calculate expression and add to stack" +msgstr "计算表达式,并将结果加入到数据栈中" + +#: kqalculate.cpp:290 kqalculate.cpp:515 kqalculate.cpp:4490 +#: kqalculate.cpp:4491 +msgid "Calculate expression" +msgstr "计算表达式" + +#: kqalculate.cpp:296 kqalculate.cpp:5915 +msgid "Store" +msgstr "暂存" + +#: kqalculate.cpp:298 +msgid "Store result as variable" +msgstr "将结果暂存为变量" + +#: kqalculate.cpp:301 kqalculate.cpp:5917 qalculateconvertunitsdialog.cpp:42 +msgid "Convert" +msgstr "换算" + +#: kqalculate.cpp:303 +msgid "Convert units in result" +msgstr "换算结果中的单位" + +#: kqalculate.cpp:313 +msgid "Enter expression here" +msgstr "在这里输入表达式" + +#: kqalculate.cpp:322 +msgid "status" +msgstr "状态" + +#: kqalculate.cpp:354 qalculateeditdataobjectdialog.cpp:71 +msgid "Exact" +msgstr "精确" + +#: kqalculate.cpp:355 +msgid "Toggle exact mode" +msgstr "切换精确模式" + +#: kqalculate.cpp:358 kqalculate.cpp:1070 +msgid "Fraction" +msgstr "分数" + +#: kqalculate.cpp:359 +msgid "Toggle fractional display" +msgstr "切换分数显示" + +#: kqalculate.cpp:363 +msgid "Numerical display" +msgstr "数值显示格式" + +#: kqalculate.cpp:366 kqalculate.cpp:1046 qalculateresultdisplay.cpp:288 +msgid "Normal" +msgstr "普通" + +#: kqalculate.cpp:367 kqalculate.cpp:1048 qalculateresultdisplay.cpp:291 +msgid "Engineering" +msgstr "工程" + +#: kqalculate.cpp:368 kqalculate.cpp:1050 qalculateresultdisplay.cpp:294 +msgid "Scientific" +msgstr "科学" + +#: kqalculate.cpp:369 +msgid "Pure" +msgstr "纯浮点" + +#: kqalculate.cpp:370 kqalculate.cpp:1054 +msgid "Simple" +msgstr "简单" + +#: kqalculate.cpp:372 +msgid "Base in result" +msgstr "结果所用进制" + +#: kqalculate.cpp:376 kqalculate.cpp:1029 qalculatesetbasedialog.cpp:35 +#: qalculatesetbasedialog.cpp:48 +msgid "Binary" +msgstr "二进制" + +#: kqalculate.cpp:377 kqalculate.cpp:1031 qalculatesetbasedialog.cpp:36 +#: qalculatesetbasedialog.cpp:49 +msgid "Octal" +msgstr "八进制" + +#: kqalculate.cpp:378 kqalculate.cpp:1033 kqalculate.cpp:1066 +#: qalculatesetbasedialog.cpp:37 qalculatesetbasedialog.cpp:50 +msgid "Decimal" +msgstr "十进制" + +#: kqalculate.cpp:379 kqalculate.cpp:1035 qalculatesetbasedialog.cpp:38 +#: qalculatesetbasedialog.cpp:51 +msgid "Hexadecimal" +msgstr "十六进制" + +#: kqalculate.cpp:380 kqalculate.cpp:1039 qalculatesetbasedialog.cpp:42 +msgid "Sexagesimal" +msgstr "六十进制" + +#: kqalculate.cpp:381 kqalculate.cpp:1041 +msgid "Time Format" +msgstr "日期格式" + +#: kqalculate.cpp:383 kqalculate.cpp:1037 +msgid "Other..." +msgstr "其它..." + +#: kqalculate.cpp:389 +msgid "f(x)" +msgstr "f(x)" + +#: kqalculate.cpp:393 +msgid "Open functions manager" +msgstr "打开函数管理器" + +#: kqalculate.cpp:395 +msgid "sqrt" +msgstr "sqrt" + +#: kqalculate.cpp:396 +msgid "Square root" +msgstr "平方根" + +#: kqalculate.cpp:399 kqalculate.cpp:947 +msgid "xy" +msgstr "xy" + +#: kqalculate.cpp:400 +msgid "Raise (Ctrl+*)" +msgstr "上标(Ctrl+))" + +#: kqalculate.cpp:403 kqalculate.cpp:946 +msgid "x2" +msgstr "x2" + +#: kqalculate.cpp:404 +msgid "Square" +msgstr "平方" + +#: kqalculate.cpp:406 +msgid "log" +msgstr "log" + +#: kqalculate.cpp:407 +msgid "Base-10 logarithm" +msgstr "以10为底的对数" + +#: kqalculate.cpp:409 +msgid "ln" +msgstr "ln" + +#: kqalculate.cpp:410 +msgid "Natural logarithm" +msgstr "自然对数" + +#: kqalculate.cpp:412 +msgid "x!" +msgstr "x!" + +#: kqalculate.cpp:413 +msgid "Factorial" +msgstr "阶乘" + +#: kqalculate.cpp:415 +msgid "cos" +msgstr "cos" + +#: kqalculate.cpp:416 +msgid "Cosine" +msgstr "余弦" + +#: kqalculate.cpp:418 +msgid "tan" +msgstr "tan" + +#: kqalculate.cpp:419 +msgid "Tangent" +msgstr "正切" + +#: kqalculate.cpp:421 +msgid "hyp" +msgstr "hyp" + +#: kqalculate.cpp:422 +msgid "Toggle hyperbolic functions" +msgstr "切换双曲函数" + +#: kqalculate.cpp:425 +msgid "inv" +msgstr "inv" + +#: kqalculate.cpp:426 +msgid "Toggle inverse functions" +msgstr "切换反函数" + +#: kqalculate.cpp:429 +msgid "sin" +msgstr "sin" + +#: kqalculate.cpp:430 +msgid "Sine" +msgstr "正弦" + +#: kqalculate.cpp:435 +msgid "Deg" +msgstr "Deg" + +#: kqalculate.cpp:436 +msgid "Angle Unit: Degrees" +msgstr "角度单位:度" + +#: kqalculate.cpp:439 +msgid "Rad" +msgstr "Rad" + +#: kqalculate.cpp:440 +msgid "Angle Unit: Radians" +msgstr "角度单位:弧度" + +#: kqalculate.cpp:443 +msgid "Gra" +msgstr "Gra" + +#: kqalculate.cpp:444 +msgid "Angle Unit: Gradians" +msgstr "角度单位:梯度" + +#: kqalculate.cpp:447 kqalculate.cpp:1094 kqalculate.cpp:1152 +#: qalculateplotdialog.cpp:126 +msgid "None" +msgstr "无" + +#: kqalculate.cpp:464 +msgid "7" +msgstr " 7" + +#: kqalculate.cpp:466 +msgid "8" +msgstr "8" + +#: kqalculate.cpp:468 +msgid "9" +msgstr "9" + +#: kqalculate.cpp:470 +msgid "4" +msgstr "4" + +#: kqalculate.cpp:472 +msgid "5" +msgstr "5" + +#: kqalculate.cpp:474 +msgid "6" +msgstr "6" + +#: kqalculate.cpp:476 +msgid "1" +msgstr "1" + +#: kqalculate.cpp:478 +msgid "2" +msgstr "2" + +#: kqalculate.cpp:480 +msgid "3" +msgstr "3" + +#: kqalculate.cpp:482 +msgid "0" +msgstr "0" + +#: kqalculate.cpp:485 +msgid "Decimal point" +msgstr "小数点" + +#: kqalculate.cpp:487 +msgid "EXP" +msgstr "EXP" + +#: kqalculate.cpp:488 +msgid "10^x (Ctrl+Shift+E)" +msgstr "10^x (Ctrl+Shift+E)" + +#: kqalculate.cpp:491 +msgid "Del" +msgstr "删除" + +#: kqalculate.cpp:494 +msgid "AC" +msgstr "AC" + +#: kqalculate.cpp:498 +msgid "Multiply" +msgstr "乘" + +#: kqalculate.cpp:501 +msgid "Divide" +msgstr "除" + +#: kqalculate.cpp:507 +msgid "Subtract" +msgstr "减" + +#: kqalculate.cpp:509 +msgid "Ans" +msgstr "Ans" + +#: kqalculate.cpp:510 +msgid "Previous result" +msgstr "前一个结果" + +#: kqalculate.cpp:512 kqalculate.cpp:4485 +msgid "Ent" +msgstr "Ent" + +#: kqalculate.cpp:535 +msgid "Index" +msgstr "索引" + +#: kqalculate.cpp:536 qalculateeditdataobjectdialog.cpp:49 +#: qalculatevariablesdialog.cpp:61 +msgid "Value" +msgstr "值" + +#: kqalculate.cpp:555 kqalculate.cpp:5921 +msgid "Up" +msgstr "上" + +#: kqalculate.cpp:556 +msgid "Move selected register up" +msgstr "向上移动选中的寄存器" + +#: kqalculate.cpp:560 kqalculate.cpp:5923 +msgid "Down" +msgstr "下" + +#: kqalculate.cpp:561 +msgid "Move selected register down" +msgstr "向上移动选中的寄存器" + +#: kqalculate.cpp:566 +msgid "Edit value of selected register" +msgstr "编辑选中的寄存器里的值" + +#: kqalculate.cpp:571 +msgid "Delete selected register" +msgstr "删除选中的寄存器" + +#: kqalculate.cpp:576 +msgid "Clear the RPN stack" +msgstr "清空逆波兰范式栈" + +#: kqalculate.cpp:592 +msgid "Keypad" +msgstr "小键盘" + +#: kqalculate.cpp:593 +msgid "Show/hide keypad" +msgstr "显示/隐藏小键盘" + +#: kqalculate.cpp:596 +msgid "History" +msgstr "历史" + +#: kqalculate.cpp:597 +msgid "Show/hide history" +msgstr "显示/隐藏历史" + +#: kqalculate.cpp:600 +msgid "RPN Stack" +msgstr "逆波兰范式栈" + +#: kqalculate.cpp:601 +msgid "Show/hide RPN stack" +msgstr "显示/隐藏逆波兰范式栈" + +#: kqalculate.cpp:716 kqalculate.cpp:2524 +msgid "RPN Register Moved" +msgstr "逆波兰范式寄存器已被移动" + +#: kqalculate.cpp:752 kqalculate.cpp:784 kqalculate.cpp:2135 +#: kqalculate.cpp:2699 kqalculate.cpp:2736 +msgid "approx." +msgstr "约" + +#: kqalculate.cpp:894 kqalculate.cpp:4810 +msgid "Load meta mode: %1" +msgstr "载入元模式:%1" + +#: kqalculate.cpp:966 +msgid "Qalculate! - Scientific Calculator" +msgstr "Qalculate! - 科学计算器" + +#: kqalculate.cpp:985 qalculateeditfunctiondialog.cpp:601 +#: qalculateresultdisplay.cpp:62 +msgid "Variable" +msgstr "变量" + +#: kqalculate.cpp:986 qalculateeditfunctiondialog.cpp:596 +#: qalculateeditmatrixvectordialog.cpp:106 qalculateimportcsvdialog.cpp:52 +#: qalculateinsertmatrixvectordialog.cpp:85 +#: qalculateinsertmatrixvectordialog.cpp:310 +msgid "Matrix" +msgstr "矩阵" + +#: kqalculate.cpp:987 qalculateeditfunctiondialog.cpp:595 +#: qalculateeditmatrixvectordialog.cpp:109 +#: qalculateinsertmatrixvectordialog.cpp:88 +#: qalculateinsertmatrixvectordialog.cpp:308 +msgid "Vector" +msgstr "向量" + +#: kqalculate.cpp:988 +msgid "Unknown Variable" +msgstr "未知变量" + +#: kqalculate.cpp:989 qalculateeditdatasetdialog.cpp:70 +#: qalculateeditfunctiondialog.cpp:71 qalculateeditfunctiondialog.cpp:599 +#: qalculateplotdialog.cpp:98 qalculateresultdisplay.cpp:92 +msgid "Function" +msgstr "函数" + +#: kqalculate.cpp:990 qalculatedatasetsdialog.cpp:64 +msgid "Data Set" +msgstr "数据集" + +#: kqalculate.cpp:991 qalculateconvertunitsdialog.cpp:68 +#: qalculateeditfunctiondialog.cpp:600 qalculateresultdisplay.cpp:67 +#: qalculateunitsdialog.cpp:67 +msgid "Unit" +msgstr "单位" + +#: kqalculate.cpp:992 +msgid "Import CSV File..." +msgstr "导入CSV文件..." + +#: kqalculate.cpp:993 +msgid "Export CSV File..." +msgstr "导出CSV文件..." + +#: kqalculate.cpp:994 +msgid "Store Result..." +msgstr "保存结果..." + +#: kqalculate.cpp:995 +msgid "Save Result Image..." +msgstr "保存结果图像..." + +#: kqalculate.cpp:996 +msgid "Save Definitions" +msgstr "保存定义" + +#: kqalculate.cpp:997 +msgid "Update Exchange Rates" +msgstr "更新汇率" + +#: kqalculate.cpp:998 +msgid "Plot Functions/Data" +msgstr "绘制函数/数据图" + +#: kqalculate.cpp:1000 +msgid "Convert Number Bases" +msgstr "转换数据进制" + +#: kqalculate.cpp:1001 qalculateperiodictabledialog.cpp:40 +msgid "Periodic Table" +msgstr "周期表" + +#: kqalculate.cpp:1008 +msgid "Show/hide main Qalculate! window" +msgstr "显示/隐藏Qalculate!主窗口" + +#: kqalculate.cpp:1011 +msgid "Configure &Global Shortcuts..." +msgstr "配置全局快捷方式(&G)..." + +#: kqalculate.cpp:1013 +msgid "Manage Variables" +msgstr "管理变量" + +#: kqalculate.cpp:1014 +msgid "Manage Functions" +msgstr "管理函数" + +#: kqalculate.cpp:1015 +msgid "Manage Units" +msgstr "管理单位" + +#: kqalculate.cpp:1016 +msgid "Manage Data Sets" +msgstr "管理数据集" + +#: kqalculate.cpp:1017 kqalculate.cpp:1150 +msgid "Factorize" +msgstr "因式分解" + +#: kqalculate.cpp:1018 kqalculate.cpp:1148 +msgid "Simplify" +msgstr "化简" + +#: kqalculate.cpp:1019 +msgid "Set Unknowns..." +msgstr "设置未知数..." + +#: kqalculate.cpp:1020 +msgid "Convert to Unit Expression..." +msgstr "转化成单位表达式..." + +#: kqalculate.cpp:1021 kqalculate.cpp:1084 +msgid "Convert to Base Units" +msgstr "转化成基本单位" + +#: kqalculate.cpp:1022 kqalculate.cpp:1086 +msgid "Convert to Best Unit" +msgstr "转化成最佳单位" + +#: kqalculate.cpp:1023 +msgid "Insert Matrix..." +msgstr "插入矩阵..." + +#: kqalculate.cpp:1024 +msgid "Insert Vector..." +msgstr "插入向量..." + +#: kqalculate.cpp:1025 +msgid "Copy Result" +msgstr "拷贝结果" + +#: kqalculate.cpp:1026 +msgid "Clear History" +msgstr "清空历史" + +#: kqalculate.cpp:1027 +msgid "Configure Qalculate!" +msgstr "配置Qaclculate!" + +#: kqalculate.cpp:1043 +msgid "Roman Numerals" +msgstr "罗马数字" + +#: kqalculate.cpp:1045 +msgid "Select Result and Expression Base..." +msgstr "选择结果和表达式的进制..." + +#: kqalculate.cpp:1052 +msgid "Purely Scientific" +msgstr "纯科学计算" + +#: kqalculate.cpp:1056 +msgid "Indicate Infinite Series" +msgstr "指出无穷序列" + +#: kqalculate.cpp:1058 +msgid "Sort Minus Last" +msgstr "" + +#: kqalculate.cpp:1060 +msgid "Negative Exponents" +msgstr "负指数" + +#: kqalculate.cpp:1062 +msgid "Show Ending Zeroes" +msgstr "显示结尾的零" + +#: kqalculate.cpp:1064 +msgid "Round Halfway Numbers to Even" +msgstr "" + +#: kqalculate.cpp:1068 +msgid "Decimal (Try Exact)" +msgstr "小数(尽量精确)" + +#: kqalculate.cpp:1072 +msgid "Combined" +msgstr "带分数" + +#: kqalculate.cpp:1074 +msgid "Enable Prefixes" +msgstr "启用前缀" + +#: kqalculate.cpp:1076 +msgid "Enable Use of All SI Prefixes" +msgstr "启用使用全部国际单位制前缀" + +#: kqalculate.cpp:1078 +msgid "Enable Denominator Prefixes" +msgstr "启用分母前缀" + +#: kqalculate.cpp:1080 +msgid "Place Units Separately" +msgstr "将单位与表达式分开" + +#: kqalculate.cpp:1082 +msgid "No Automatic Conversion" +msgstr "不自动换算" + +#: kqalculate.cpp:1088 +msgid "Degrees" +msgstr "度" + +#: kqalculate.cpp:1090 +msgid "Radians" +msgstr "弧度" + +#: kqalculate.cpp:1092 +msgid "Gradians" +msgstr "梯度" + +#: kqalculate.cpp:1096 +msgid "Abbreviate Names" +msgstr "使用缩写" + +#: kqalculate.cpp:1098 +msgid "Enable Variables" +msgstr "启用变量" + +#: kqalculate.cpp:1100 +msgid "Enable Functions" +msgstr "启用函数" + +#: kqalculate.cpp:1102 +msgid "Enable Units" +msgstr "启用单位" + +#: kqalculate.cpp:1104 +msgid "Enable Unknowns" +msgstr "启用未知数" + +#: kqalculate.cpp:1106 +msgid "Calculate Variables" +msgstr "计算变量" + +#: kqalculate.cpp:1108 +msgid "Allow Complex Result" +msgstr "允许复数结果" + +#: kqalculate.cpp:1110 +msgid "Allow Infinite Result" +msgstr "允许无穷结果" + +#: kqalculate.cpp:1112 +msgid "Try Exact" +msgstr "尝试精确" + +#: kqalculate.cpp:1114 +msgid "Always Exact" +msgstr "总是精确" + +#: kqalculate.cpp:1116 qalculateeditdataobjectdialog.cpp:70 +msgid "Approximate" +msgstr "近似" + +#: kqalculate.cpp:1118 kqalculate.cpp:1132 +#: qalculateeditunknownvariabledialog.cpp:65 +#: qalculateeditunknownvariabledialog.cpp:78 +#: qalculateperiodictabledialog.cpp:235 +msgid "Unknown" +msgstr "未知" + +#: kqalculate.cpp:1120 qalculateeditunknownvariabledialog.cpp:66 +msgid "Not Matrix" +msgstr "不是矩阵" + +#: kqalculate.cpp:1122 qalculateeditdatasetdialog.cpp:468 +#: qalculateeditfunctiondialog.cpp:590 +#: qalculateeditunknownvariabledialog.cpp:67 +msgid "Number" +msgstr "数字" + +#: kqalculate.cpp:1124 +msgid "Complex" +msgstr "复数" + +#: kqalculate.cpp:1126 +msgid "Real" +msgstr "实数" + +#: kqalculate.cpp:1128 +msgid "Rational" +msgstr "有理数" + +#: kqalculate.cpp:1130 qalculateeditfunctiondialog.cpp:591 +#: qalculateeditunknownvariabledialog.cpp:71 +msgid "Integer" +msgstr "整数" + +#: kqalculate.cpp:1134 qalculateeditunknownvariabledialog.cpp:83 +msgid "Non-Zero" +msgstr "非零" + +#: kqalculate.cpp:1136 qalculateeditunknownvariabledialog.cpp:79 +msgid "Positive" +msgstr "为正" + +#: kqalculate.cpp:1138 qalculateeditunknownvariabledialog.cpp:80 +msgid "Non-Negative" +msgstr "非负" + +#: kqalculate.cpp:1140 qalculateeditunknownvariabledialog.cpp:81 +msgid "Negative" +msgstr "为负" + +#: kqalculate.cpp:1142 qalculateeditunknownvariabledialog.cpp:82 +msgid "Non-Positive" +msgstr "非正" + +#: kqalculate.cpp:1144 +msgid "Non-Zero Denominators" +msgstr "非零分母" + +#: kqalculate.cpp:1146 +msgid "Warn About Denominators Assumed Non-Zero" +msgstr "假设分母非零时警告" + +#: kqalculate.cpp:1154 +msgid "Read Precision" +msgstr "读取精度" + +#: kqalculate.cpp:1156 +msgid "Limit Implicit Multiplication" +msgstr "限制暗示乘法" + +#: kqalculate.cpp:1158 +msgid "RPN Mode" +msgstr "逆波兰范式模式" + +#: kqalculate.cpp:1160 +msgid "RPN Syntax" +msgstr "逆波兰语法" + +#: kqalculate.cpp:1162 qalculateprecisiondialog.cpp:31 +msgid "Precision" +msgstr "精度" + +#: kqalculate.cpp:1163 qalculatedecimalsdialog.cpp:27 +msgid "Decimals" +msgstr "小数点" + +#: kqalculate.cpp:1164 +msgid "Save Mode..." +msgstr "保存模式..." + +#: kqalculate.cpp:1165 +msgid "Delete Mode..." +msgstr "删除模式..." + +#: kqalculate.cpp:1167 +msgid "Save Default Mode" +msgstr "保存缺省模式" + +#: kqalculate.cpp:1168 +msgid "Clear Stack" +msgstr "清空栈" + +#: kqalculate.cpp:1172 +msgid "Exp RPN Operation" +msgstr "" + +#: kqalculate.cpp:1865 +msgid "and" +msgstr "and" + +#: kqalculate.cpp:1870 +msgid "or" +msgstr "or" + +#: kqalculate.cpp:2119 +msgid "undefined" +msgstr "undefined" + +#: kqalculate.cpp:2161 +msgid "EXACT" +msgstr "精确" + +#: kqalculate.cpp:2164 +msgid "APPROX" +msgstr "近似" + +#: kqalculate.cpp:2168 +msgid "RPN" +msgstr "逆波兰" + +#: kqalculate.cpp:2176 +msgid "BIN" +msgstr "二进制" + +#: kqalculate.cpp:2181 +msgid "OCT" +msgstr "八进制" + +#: kqalculate.cpp:2186 +msgid "HEX" +msgstr "十六进制" + +#: kqalculate.cpp:2191 +msgid "ROMAN" +msgstr "罗马数字" + +#: kqalculate.cpp:2203 +msgid "DEG" +msgstr "度" + +#: kqalculate.cpp:2208 +msgid "RAD" +msgstr "弧度" + +#: kqalculate.cpp:2213 +msgid "GRA" +msgstr "梯度" + +#: kqalculate.cpp:2220 +msgid "PREC" +msgstr "精度" + +#: kqalculate.cpp:2225 +msgid "FUNC" +msgstr "函数" + +#: kqalculate.cpp:2231 +msgid "UNIT" +msgstr "单位" + +#: kqalculate.cpp:2237 +msgid "VAR" +msgstr "变量" + +#: kqalculate.cpp:2243 +msgid "INF" +msgstr "无穷" + +#: kqalculate.cpp:2249 +msgid "CPLX" +msgstr "复数" + +#: kqalculate.cpp:2330 kqalculate.cpp:2348 kqalculate.cpp:2578 +msgid "aborted" +msgstr "已终止" + +#: kqalculate.cpp:2349 +msgid "calculation was aborted" +msgstr "计算已被终止" + +#: kqalculate.cpp:2585 +msgid "result processing was aborted" +msgstr "结果处理已被终止" + +#: kqalculate.cpp:2633 +msgid "Processing..." +msgstr "正在处理..." + +#: kqalculate.cpp:2637 kqalculate.cpp:2882 kqalculate.cpp:3142 +msgid "Abort" +msgstr "终止" + +#: kqalculate.cpp:2870 +msgid "Factorizing..." +msgstr "正在因式分解..." + +#: kqalculate.cpp:2874 +msgid "Simplifying..." +msgstr "正在化简..." + +#: kqalculate.cpp:3138 +msgid "Calculating..." +msgstr "正在计算..." + +#: kqalculate.cpp:3188 +msgid "RPN Operation" +msgstr "逆波兰范式操作" + +#: kqalculate.cpp:3256 +msgid "Errors" +msgstr "错误" + +#: kqalculate.cpp:3257 +msgid "Warnings" +msgstr "警告" + +#: kqalculate.cpp:3267 +msgid "Couldn't write definitions" +msgstr "无法写定义" + +#: kqalculate.cpp:3535 +msgid "Prefixes" +msgstr "前缀" + +#: kqalculate.cpp:3662 +msgid "No Prefix" +msgstr "无前缀" + +#: kqalculate.cpp:3813 qalculatevariablesdialog.cpp:191 +#: qalculatevariablesdialog.cpp:337 +msgid "Variable does not exist anymore." +msgstr "变量不再存在。" + +#: kqalculate.cpp:3829 qalculateconvertunitsdialog.cpp:153 +#: qalculateunitsdialog.cpp:223 qalculateunitsdialog.cpp:337 +msgid "Unit does not exist anymore." +msgstr "单位不再存在。" + +#: kqalculate.cpp:3902 +msgid "Failed to download exchange rates from ECB." +msgstr "从ECB下载汇率失败。" + +#: kqalculate.cpp:4749 +msgid "Save Mode" +msgstr "保存模式" + +#: kqalculate.cpp:4752 +msgid "Mode name:" +msgstr "模式名:" + +#: kqalculate.cpp:4762 +msgid "Shortcut:" +msgstr "快捷方式:" + +#: kqalculate.cpp:4789 +msgid "Empty mode name." +msgstr "空模式名。" + +#: kqalculate.cpp:4792 +msgid "Preset mode cannot be overwritten." +msgstr "不能覆盖预定义模式。" + +#: kqalculate.cpp:4824 +msgid "Delete Mode" +msgstr "删除模式" + +#: kqalculate.cpp:4824 +msgid "Mode:" +msgstr "模式:" + +#: kqalculate.cpp:4998 +msgid "log10 function not found." +msgstr "未找到log10函数。" + +#: kqalculate.cpp:5542 main.cpp:156 main.cpp:159 main.cpp:160 main.cpp:161 +#: main.cpp:162 +msgid "Temporary" +msgstr "临时" + +#: kqalculate.cpp:5564 kqalculate.cpp:5591 qalculatefunctionsdialog.cpp:191 +#: qalculatefunctionsdialog.cpp:300 +msgid "Function does not exist anymore." +msgstr "函数不再存在。" + +#: kqalculate.cpp:5694 kqalculate.cpp:5730 +msgid "My Variables" +msgstr "我的变量" + +#: kqalculate.cpp:5706 qalculateimportcsvdialog.cpp:56 +msgid "Vectors" +msgstr "向量" + +#: kqalculate.cpp:5718 +msgid "Matrices" +msgstr "矩阵" + +#: kqalculate.cpp:5759 qalculateplotdialog.cpp:726 +msgid "Save Image" +msgstr "保存图像" + +#: kqalculate.cpp:5764 qalculateplotdialog.cpp:731 +msgid "A file named \"%1\" already exists. Are you sure you want to overwrite it?" +msgstr "文件\"%1\"已存在。您确定要覆盖它吗?" + +#: kqalculate.cpp:5764 qalculateplotdialog.cpp:731 +msgid "Overwrite File?" +msgstr "覆盖文件?" + +#: kqalculate.cpp:5764 qalculateplotdialog.cpp:731 +msgid "&Overwrite" +msgstr "覆盖(&O)" + +#: kqalculate.cpp:5798 +msgid "Failed to save image." +msgstr "保存问图像失败。" + +#: kqalculate.cpp:6024 +msgid "No unknowns in result." +msgstr "在结果中不存在未知数。" + +#: kqalculate.cpp:6027 +msgid "Set Unknowns" +msgstr "设置未知数。" + +#: kqalculate.cpp:6191 +msgid "Too many arguments for %1()." +msgstr "%1()的参数过多。" + +#: kqalculate.cpp:6217 qalculatedatasetsdialog.cpp:342 +#: qalculatefunctionsdialog.cpp:343 qalculateresultdisplay.cpp:120 +msgid "argument" +msgstr "参数" + +#: kqalculate.cpp:6439 kqalculate.cpp:6443 +msgid "Edit Expression" +msgstr "编辑表达式" + +#: kqalculate.cpp:6448 +msgid "Edit Result" +msgstr "编辑结果" + +#: kqalculate.cpp:6451 +msgid "Insert Result Variable" +msgstr "插入结果变量" + +#: main.cpp:45 +msgid "A powerful and easy to use desktop calculator" +msgstr "一个强大而且易用的桌面计算器" + +#: main.cpp:51 +msgid "Calculate X11-clipboard content (selected text)" +msgstr "计算X11剪贴板里的内容(选中的文本)" + +#: main.cpp:52 +msgid "Initial expression to calculate" +msgstr "初始化表达式进行计算" + +#: main.cpp:134 +msgid "Enter a mathematical expression above.
Ex. 5 + 2 / 3" +msgstr "" +"在上面输入一个数学表达式。\n" +"例如,5 + 2 / 3" + +#: main.cpp:143 +msgid "" +"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" +"\n" +"Do you want to fetch exchange rates now from the Internet?" +msgstr "" +"您需要下载汇率,才能在不同货币间进行换算。您可以之后通过\"文件\"菜单里的\"更新汇率\"项来获取当前的汇率。 \n" +"\n" +"现在是否从因特网下载汇率?" + +#: main.cpp:143 +msgid "Update exchange rates?" +msgstr "更新汇率?" + +#: main.cpp:155 +msgid "ans" +msgstr "ans" + +#: main.cpp:156 +msgid "Last Answer" +msgstr "最后一个答案" + +#: main.cpp:157 +msgid "answer" +msgstr "答案" + +#: main.cpp:159 +msgid "Answer 2" +msgstr "答案2" + +#: main.cpp:160 +msgid "Answer 3" +msgstr "答案3" + +#: main.cpp:161 +msgid "Answer 4" +msgstr "答案4" + +#: main.cpp:162 +msgid "Answer 5" +msgstr "答案5" + +#: main.cpp:166 +msgid "Failed to load global definitions!" +msgstr "载入全局定义失败!" + +#: main.cpp:290 +msgid "Qalculate!" +msgstr "Qalculate!" + +#: preferences.cpp:208 +msgid "Preset" +msgstr "预设参数" + +#: preferences.cpp:669 +#, c-format +msgid "" +"Couldn't write preferences to\n" +"%s" +msgstr "" +"无法将偏好设置写入\n" +"%s" + +#: qalculateconvertnumberbasesdialog.cpp:31 qalculatesetbasedialog.cpp:29 +msgid "Number Bases" +msgstr "数字进制" + +#: qalculateconvertnumberbasesdialog.cpp:37 +msgid "Decimal:" +msgstr "十进制:" + +#: qalculateconvertnumberbasesdialog.cpp:41 +msgid "Binary:" +msgstr "二进制:" + +#: qalculateconvertnumberbasesdialog.cpp:45 +msgid "Octal:" +msgstr "八进制:" + +#: qalculateconvertnumberbasesdialog.cpp:49 +msgid "Hexadecimal:" +msgstr "十六进制:" + +#: qalculateconvertunitsdialog.cpp:44 +msgid "Selector" +msgstr "选择器" + +#: qalculateconvertunitsdialog.cpp:50 qalculateeditdatasetdialog.cpp:482 +msgid "Unit expression:" +msgstr "单位表达式:" + +#: qalculateconvertunitsdialog.cpp:63 qalculatefunctionsdialog.cpp:55 +#: qalculateunitsdialog.cpp:63 qalculatevariablesdialog.cpp:57 +msgid "Category" +msgstr "分类" + +#: qalculateconvertunitsdialog.cpp:85 qalculateconvertunitsdialog.cpp:86 +#: qalculateconvertunitsdialog.cpp:141 qalculateconvertunitsdialog.cpp:180 +#: qalculatefunctionsdialog.cpp:118 qalculatefunctionsdialog.cpp:119 +#: qalculatefunctionsdialog.cpp:183 qalculatefunctionsdialog.cpp:505 +#: qalculateunitsdialog.cpp:150 qalculateunitsdialog.cpp:151 +#: qalculateunitsdialog.cpp:215 qalculateunitsdialog.cpp:416 +#: qalculatevariablesdialog.cpp:116 qalculatevariablesdialog.cpp:117 +#: qalculatevariablesdialog.cpp:183 qalculatevariablesdialog.cpp:462 +msgid "All" +msgstr "全部" + +#: qalculateconvertunitsdialog.cpp:132 qalculateconvertunitsdialog.cpp:133 +#: qalculateconvertunitsdialog.cpp:134 qalculateconvertunitsdialog.cpp:182 +#: qalculatefunctionsdialog.cpp:165 qalculatefunctionsdialog.cpp:166 +#: qalculatefunctionsdialog.cpp:167 qalculatefunctionsdialog.cpp:236 +#: qalculatefunctionsdialog.cpp:262 qalculatefunctionsdialog.cpp:285 +#: qalculatefunctionsdialog.cpp:507 qalculateunitsdialog.cpp:197 +#: qalculateunitsdialog.cpp:198 qalculateunitsdialog.cpp:199 +#: qalculateunitsdialog.cpp:273 qalculateunitsdialog.cpp:299 +#: qalculateunitsdialog.cpp:322 qalculateunitsdialog.cpp:418 +#: qalculatevariablesdialog.cpp:165 qalculatevariablesdialog.cpp:166 +#: qalculatevariablesdialog.cpp:167 qalculatevariablesdialog.cpp:258 +#: qalculatevariablesdialog.cpp:284 qalculatevariablesdialog.cpp:322 +#: qalculatevariablesdialog.cpp:464 +msgid "Uncategorized" +msgstr "未分类" + +#: qalculatedatasetsdialog.cpp:46 qalculateeditdatasetdialog.cpp:232 +msgid "Data Sets" +msgstr "数据集" + +#: qalculatedatasetsdialog.cpp:61 +msgid "Data Sets:" +msgstr "数据集:" + +#: qalculatedatasetsdialog.cpp:68 qalculatedatasetsdialog.cpp:91 +#: qalculateeditdatasetdialog.cpp:107 qalculateeditdatasetdialog.cpp:629 +#: qalculateeditfunctiondialog.cpp:133 qalculateeditfunctiondialog.cpp:492 +#: qalculateeditnamesdialog.cpp:64 qalculatefunctionsdialog.cpp:67 +#: qalculateunitsdialog.cpp:91 qalculatevariablesdialog.cpp:66 +msgid "New" +msgstr "新建" + +#: qalculatedatasetsdialog.cpp:77 qalculateeditdatasetdialog.cpp:79 +#: qalculateeditdatasetdialog.cpp:456 qalculateeditfunctiondialog.cpp:98 +msgid "Description:" +msgstr "描述:" + +#: qalculatedatasetsdialog.cpp:84 +msgid "Objects:" +msgstr "对象:" + +#: qalculatedatasetsdialog.cpp:87 qalculateeditdatasetdialog.cpp:236 +#: qalculateeditfunctiondialog.cpp:598 +msgid "Object" +msgstr "对象" + +#: qalculatedatasetsdialog.cpp:100 +msgid "Attributes:" +msgstr "属性:" + +#: qalculatedatasetsdialog.cpp:157 qalculatedatasetsdialog.cpp:218 +msgid "Data set does not exist anymore." +msgstr "数据集不再存在。" + +#: qalculatedatasetsdialog.cpp:300 qalculateeditdatasetdialog.cpp:195 +#: qalculatefunctionsdialog.cpp:456 +msgid "key" +msgstr "关键字" + +#: qalculatedatasetsdialog.cpp:316 +msgid "Data Retrieval Function" +msgstr "数据获取函数" + +#: qalculatedecimalsdialog.cpp:31 +msgid "Max decimals:" +msgstr "最大精度位数:" + +#: qalculatedecimalsdialog.cpp:39 +msgid "Min decimals:" +msgstr "最小精度位数:" + +#: qalculateeditdataobjectdialog.cpp:30 qalculateeditdataobjectdialog.cpp:40 +msgid "Edit Object" +msgstr "编辑对象" + +#: qalculateeditdataobjectdialog.cpp:42 +msgid "New Object" +msgstr "新对象" + +#: qalculateeditdataobjectdialog.cpp:48 qalculateeditdatasetdialog.cpp:242 +msgid "Property" +msgstr "属性" + +#. i18n: file ./qalculate_kdeui.rc line 116 +#: qalculateeditdataobjectdialog.cpp:51 rc.cpp:39 +#, no-c-format +msgid "Approximation" +msgstr "近似" + +#: qalculateeditdatasetdialog.cpp:53 qalculateeditdatasetdialog.cpp:307 +msgid "Edit Data Set" +msgstr "编辑数据集" + +#: qalculateeditdatasetdialog.cpp:68 qalculateeditfunctiondialog.cpp:70 +#: qalculatepreferencesdialog.cpp:157 +msgid "General" +msgstr "常规" + +#: qalculateeditdatasetdialog.cpp:73 qalculateplotdialog.cpp:86 +#: qalculateplotdialog.cpp:189 +msgid "Title:" +msgstr "标题:" + +#: qalculateeditdatasetdialog.cpp:76 +msgid "Data file:" +msgstr "数据文件:" + +#: qalculateeditdatasetdialog.cpp:87 +msgid "Copyright:" +msgstr "版权:" + +#: qalculateeditdatasetdialog.cpp:97 +msgid "Properties:" +msgstr "属性:" + +#: qalculateeditdatasetdialog.cpp:99 qalculateplotdialog.cpp:153 +msgid "Title" +msgstr "标题" + +#: qalculateeditdatasetdialog.cpp:100 qalculateeditdatasetdialog.cpp:620 +#: qalculateeditfunctiondialog.cpp:124 qalculateeditnamesdialog.cpp:41 +#: qalculateeditunitdialog.cpp:50 +msgid "Name" +msgstr "名称" + +#: qalculateeditdatasetdialog.cpp:101 qalculateeditfunctiondialog.cpp:125 +#: qalculateeditunitdialog.cpp:75 qalculateeditunknownvariabledialog.cpp:60 +msgid "Type" +msgstr "类别" + +#: qalculateeditdatasetdialog.cpp:115 qalculateeditdatasetdialog.cpp:442 +#: qalculateeditfunctiondialog.cpp:74 qalculateeditfunctiondialog.cpp:583 +#: qalculateeditmatrixvectordialog.cpp:78 qalculateeditunitdialog.cpp:55 +#: qalculateeditunknownvariabledialog.cpp:47 +#: qalculateeditvariabledialog.cpp:49 qalculateimportcsvdialog.cpp:60 +msgid "Name:" +msgstr "名称:" + +#: qalculateeditdatasetdialog.cpp:124 qalculateeditdatasetdialog.cpp:451 +#: qalculateeditfunctiondialog.cpp:83 qalculateeditmatrixvectordialog.cpp:87 +#: qalculateeditunitdialog.cpp:64 qalculateeditunknownvariabledialog.cpp:56 +#: qalculateeditvariabledialog.cpp:60 +msgid "Names Details" +msgstr "名称详细信息" + +#: qalculateeditdatasetdialog.cpp:126 +msgid "Object argument name:" +msgstr "对象参数名:" + +#: qalculateeditdatasetdialog.cpp:129 +msgid "Property argument name:" +msgstr "属性参数名:" + +#: qalculateeditdatasetdialog.cpp:132 +msgid "Default property:" +msgstr "缺省属性:" + +#: qalculateeditdatasetdialog.cpp:173 +msgid "text" +msgstr "文字" + +#: qalculateeditdatasetdialog.cpp:178 qalculateeditdatasetdialog.cpp:186 +msgid "approximate" +msgstr "近似" + +#: qalculateeditdatasetdialog.cpp:181 qalculateexpressionedit.cpp:696 +#: qalculatevariablesdialog.cpp:428 +msgid "number" +msgstr "数字" + +#: qalculateeditdatasetdialog.cpp:189 +msgid "expression" +msgstr "表达式" + +#: qalculateeditdatasetdialog.cpp:213 qalculateeditdatasetdialog.cpp:499 +#: qalculateeditfunctiondialog.cpp:190 qalculateeditmatrixvectordialog.cpp:185 +#: qalculateeditunitdialog.cpp:146 qalculateeditunknownvariabledialog.cpp:132 +#: qalculateeditvariabledialog.cpp:102 +msgid "Empty name field" +msgstr "空白名称域" + +#: qalculateeditdatasetdialog.cpp:217 qalculateeditfunctiondialog.cpp:201 +msgid "" +"A function with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" +"同名函数已存在。\n" +"您想要覆盖它吗?" + +#: qalculateeditdatasetdialog.cpp:309 +msgid "Edit Data Set (global)" +msgstr "编辑(全局)数据集" + +#: qalculateeditdatasetdialog.cpp:311 +msgid "New Data Set" +msgstr "新数据集" + +#: qalculateeditdatasetdialog.cpp:322 +msgid "info" +msgstr "信息" + +#: qalculateeditdatasetdialog.cpp:435 qalculateeditdatasetdialog.cpp:548 +msgid "Edit Property" +msgstr "编辑属性" + +#: qalculateeditdatasetdialog.cpp:453 qalculateeditfunctiondialog.cpp:90 +#: qalculateeditmatrixvectordialog.cpp:93 qalculateeditunitdialog.cpp:66 +#: qalculateeditunknownvariabledialog.cpp:90 +#: qalculateeditvariabledialog.cpp:80 qalculateimportcsvdialog.cpp:63 +msgid "Descriptive name:" +msgstr "描述性名称:" + +#: qalculateeditdatasetdialog.cpp:464 +msgid "Value type:" +msgstr "值类型:" + +#: qalculateeditdatasetdialog.cpp:467 qalculateeditfunctiondialog.cpp:593 +msgid "Text" +msgstr "文字" + +#: qalculateeditdatasetdialog.cpp:469 qalculateeditfunctiondialog.cpp:482 +#: qalculateplotdialog.cpp:154 +msgid "Expression" +msgstr "表达式" + +#: qalculateeditdatasetdialog.cpp:474 +msgid "Use as key" +msgstr "用作关键字" + +#: qalculateeditdatasetdialog.cpp:476 +msgid "Approximate value" +msgstr "近似值" + +#: qalculateeditdatasetdialog.cpp:478 +msgid "Case sensitive value" +msgstr "大小写敏感值" + +#: qalculateeditdatasetdialog.cpp:480 +msgid "Value uses brackets" +msgstr "在值中使用方括号" + +#: qalculateeditdatasetdialog.cpp:550 +msgid "New Property" +msgstr "新建属性" + +#: qalculateeditdatasetdialog.cpp:615 qalculateeditnamesdialog.cpp:34 +msgid "Edit Names" +msgstr "编辑名称" + +#: qalculateeditdatasetdialog.cpp:621 qalculateeditfunctiondialog.cpp:481 +#: qalculateeditnamesdialog.cpp:46 +msgid "Reference" +msgstr "引用" + +#: qalculateeditfunctiondialog.cpp:55 qalculateeditfunctiondialog.cpp:286 +msgid "Edit Function" +msgstr "编辑函数" + +#: qalculateeditfunctiondialog.cpp:85 qalculateeditmatrixvectordialog.cpp:89 +#: qalculateeditunitdialog.cpp:87 qalculateeditunknownvariabledialog.cpp:85 +#: qalculateeditvariabledialog.cpp:74 qalculateimportcsvdialog.cpp:66 +msgid "Category:" +msgstr "类别:" + +#: qalculateeditfunctiondialog.cpp:96 +msgid "Hide function" +msgstr "隐藏函数" + +#: qalculateeditfunctiondialog.cpp:106 qalculateplotdialog.cpp:89 +msgid "Expression:" +msgstr "表达式:" + +#: qalculateeditfunctiondialog.cpp:115 +msgid "Condition:" +msgstr "条件:" + +#: qalculateeditfunctiondialog.cpp:120 qalculateeditfunctiondialog.cpp:476 +msgid "Sub-Functions" +msgstr "子函数" + +#: qalculateeditfunctiondialog.cpp:122 +msgid "Arguments:" +msgstr "自变量:" + +#: qalculateeditfunctiondialog.cpp:197 +msgid "Empty expression field" +msgstr "空白表达式项" + +#: qalculateeditfunctiondialog.cpp:288 +msgid "Edit Function (global)" +msgstr "编辑(全局)函数" + +#: qalculateeditfunctiondialog.cpp:290 +msgid "New Function" +msgstr "新建函数" + +#: qalculateeditfunctiondialog.cpp:483 +msgid "Precalculate" +msgstr "预计算" + +#: qalculateeditfunctiondialog.cpp:579 qalculateeditfunctiondialog.cpp:675 +msgid "Edit Argument" +msgstr "编辑自变量" + +#: qalculateeditfunctiondialog.cpp:586 +msgid "Type:" +msgstr "类型:" + +#: qalculateeditfunctiondialog.cpp:589 +msgid "Free" +msgstr "自由变量" + +#: qalculateeditfunctiondialog.cpp:592 +msgid "Symbol" +msgstr "符号" + +#: qalculateeditfunctiondialog.cpp:594 qalculateinsertfunctiondialog.cpp:353 +msgid "Date" +msgstr "日期" + +#: qalculateeditfunctiondialog.cpp:597 +msgid "Boolean" +msgstr "逻辑型" + +#: qalculateeditfunctiondialog.cpp:603 +msgid "Angle" +msgstr "角度" + +#: qalculateeditfunctiondialog.cpp:605 +msgid "Enable rules and type test" +msgstr "启用规则和类型测试" + +#: qalculateeditfunctiondialog.cpp:607 +msgid "Custom condition:" +msgstr "自定义条件:" + +#: qalculateeditfunctiondialog.cpp:611 +msgid "Allow matrix" +msgstr "允许矩阵" + +#: qalculateeditfunctiondialog.cpp:613 +msgid "Forbid zero" +msgstr "禁止出现零" + +#: qalculateeditfunctiondialog.cpp:615 +msgid "Allow complex" +msgstr "允许复数" + +#: qalculateeditfunctiondialog.cpp:617 qalculateplotdialog.cpp:164 +msgid "Min:" +msgstr "最小值:" + +#: qalculateeditfunctiondialog.cpp:624 qalculateeditfunctiondialog.cpp:633 +msgid "Include equals" +msgstr "包含相等关系" + +#: qalculateeditfunctiondialog.cpp:626 qalculateplotdialog.cpp:167 +msgid "Max:" +msgstr "最大值:" + +#: qalculateeditfunctiondialog.cpp:677 +msgid "New Argument" +msgstr "新自变量" + +#: qalculateeditmatrixvectordialog.cpp:71 +#: qalculateeditunknownvariabledialog.cpp:40 +#: qalculateeditvariabledialog.cpp:41 qalculateeditvariabledialog.cpp:180 +#: qalculateinsertmatrixvectordialog.cpp:71 +msgid "Edit Variable" +msgstr "编辑变量" + +#: qalculateeditmatrixvectordialog.cpp:96 +#: qalculateinsertmatrixvectordialog.cpp:75 +msgid "Rows:" +msgstr "行:" + +#: qalculateeditmatrixvectordialog.cpp:99 +#: qalculateinsertmatrixvectordialog.cpp:78 +msgid "Columns:" +msgstr "列:" + +#: qalculateeditmatrixvectordialog.cpp:112 +#: qalculateeditmatrixvectordialog.cpp:133 +#: qalculateeditmatrixvectordialog.cpp:295 +#: qalculateinsertmatrixvectordialog.cpp:91 +#: qalculateinsertmatrixvectordialog.cpp:115 +#: qalculateinsertmatrixvectordialog.cpp:275 +msgid "Elements:" +msgstr "元素:" + +#: qalculateeditmatrixvectordialog.cpp:146 +#: qalculateeditmatrixvectordialog.cpp:292 +#: qalculateinsertmatrixvectordialog.cpp:128 +#: qalculateinsertmatrixvectordialog.cpp:272 +msgid "Elements (in horizontal order):" +msgstr "元素(水平顺序):" + +#: qalculateeditmatrixvectordialog.cpp:189 +#: qalculateeditunknownvariabledialog.cpp:136 +#: qalculateeditvariabledialog.cpp:114 +msgid "" +"An unit or variable with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" +"同名的单位或变量已存在。\n" +"您要覆盖它吗?" + +#: qalculateeditmatrixvectordialog.cpp:301 +msgid "Edit Vector" +msgstr "编辑向量" + +#: qalculateeditmatrixvectordialog.cpp:303 +msgid "Edit Vector (global)" +msgstr "编辑向量(全局)" + +#: qalculateeditmatrixvectordialog.cpp:305 +msgid "New Vector" +msgstr "新建向量" + +#: qalculateeditmatrixvectordialog.cpp:310 +msgid "Edit Matrix" +msgstr "编辑矩阵" + +#: qalculateeditmatrixvectordialog.cpp:312 +msgid "Edit Matrix (global)" +msgstr "编辑矩阵(全局)" + +#: qalculateeditmatrixvectordialog.cpp:314 +msgid "New Matrix" +msgstr "新建矩阵" + +#: qalculateeditnamesdialog.cpp:42 +msgid "Abbreviation" +msgstr "缩写" + +#: qalculateeditnamesdialog.cpp:44 +msgid "Plural" +msgstr "复数" + +#: qalculateeditnamesdialog.cpp:48 +msgid "Avoid Input" +msgstr "避免输入" + +#: qalculateeditnamesdialog.cpp:50 +msgid "Unicode" +msgstr "Unicode" + +#: qalculateeditnamesdialog.cpp:52 +msgid "Suffix" +msgstr "后缀" + +#: qalculateeditnamesdialog.cpp:54 +msgid "Case Sensitive" +msgstr "大小写敏感" + +#: qalculateeditunitdialog.cpp:43 qalculateeditunitdialog.cpp:287 +msgid "Edit Unit" +msgstr "编辑单位" + +#: qalculateeditunitdialog.cpp:72 +msgid "Hide unit" +msgstr "隐藏单位" + +#: qalculateeditunitdialog.cpp:80 +msgid "Class:" +msgstr "类别:" + +#: qalculateeditunitdialog.cpp:83 +msgid "Base Unit" +msgstr "基准单位" + +#: qalculateeditunitdialog.cpp:84 +msgid "Alias" +msgstr "别名" + +#: qalculateeditunitdialog.cpp:85 +msgid "Composite Unit" +msgstr "复合单位" + +#: qalculateeditunitdialog.cpp:92 +msgid "System:" +msgstr "体系:" + +#: qalculateeditunitdialog.cpp:95 +msgid "SI" +msgstr "国际单位制" + +#: qalculateeditunitdialog.cpp:96 +msgid "CGS" +msgstr "CGS" + +#: qalculateeditunitdialog.cpp:97 +msgid "Imperial" +msgstr "英制" + +#: qalculateeditunitdialog.cpp:98 +msgid "US Survey" +msgstr "美制" + +#: qalculateeditunitdialog.cpp:102 +msgid "Relation" +msgstr "关系" + +#: qalculateeditunitdialog.cpp:107 +msgid "Base unit:" +msgstr "基准单位:" + +#: qalculateeditunitdialog.cpp:110 +msgid "Exponent:" +msgstr "指数:" + +#: qalculateeditunitdialog.cpp:114 +msgid "Relation:" +msgstr "关系:" + +#: qalculateeditunitdialog.cpp:121 +msgid "Relation is exact" +msgstr "" + +#: qalculateeditunitdialog.cpp:123 +msgid "Inverse relation:" +msgstr "倒转关系:" + +#: qalculateeditunitdialog.cpp:150 +msgid "" +"A variable or unit with the same name already exists.\n" +"Do you want to overwrite it?" +msgstr "" +"同名的变量或单位已存在。\n" +"您是否要覆盖它?" + +#: qalculateeditunitdialog.cpp:175 qalculateeditunitdialog.cpp:219 +msgid "Base unit does not exist" +msgstr "基准单位不存在" + +#: qalculateeditunitdialog.cpp:289 +msgid "Edit Unit (global)" +msgstr "编辑单位(全局)" + +#: qalculateeditunitdialog.cpp:291 +msgid "New Unit" +msgstr "新单位" + +#: qalculateeditunknownvariabledialog.cpp:58 +msgid "Custom assumptions:" +msgstr "自定义假设:" + +#: qalculateeditunknownvariabledialog.cpp:68 +msgid "Complex Number" +msgstr "复数" + +#: qalculateeditunknownvariabledialog.cpp:69 +msgid "Real Number" +msgstr "实数" + +#: qalculateeditunknownvariabledialog.cpp:70 +msgid "Rational Number" +msgstr "有理数" + +#: qalculateeditunknownvariabledialog.cpp:73 +msgid "Sign" +msgstr "符号" + +#: qalculateeditunknownvariabledialog.cpp:199 +msgid "Edit Unknown Variable" +msgstr "编辑未知数变量" + +#: qalculateeditunknownvariabledialog.cpp:201 +msgid "Edit Unknown Variable (global)" +msgstr "编辑未知数变量(全局)" + +#: qalculateeditunknownvariabledialog.cpp:203 +msgid "New Unknown Variable" +msgstr "新建未知数变量" + +#: qalculateeditvariabledialog.cpp:63 qalculateinsertfunctiondialog.cpp:91 +msgid "Value:" +msgstr "值:" + +#: qalculateeditvariabledialog.cpp:71 +msgid "Value is exact" +msgstr "" + +#: qalculateeditvariabledialog.cpp:110 +msgid "Empty value field" +msgstr "空白值项" + +#: qalculateeditvariabledialog.cpp:182 +msgid "Edit Variable (global)" +msgstr "编辑变量(全局)" + +#: qalculateeditvariabledialog.cpp:185 +msgid "New Variable" +msgstr "新变量" + +#: qalculateexportcsvdialog.cpp:37 qalculateexportcsvdialog.cpp:54 +msgid "Export CSV File" +msgstr "输出CSV文件" + +#: qalculateexportcsvdialog.cpp:42 +msgid "Current result" +msgstr "当前结果" + +#: qalculateexportcsvdialog.cpp:46 +msgid "Matrix/vector variable" +msgstr "矩阵/向量变量" + +#: qalculateexportcsvdialog.cpp:51 qalculateimportcsvdialog.cpp:43 +msgid "File:" +msgstr "文件:" + +#: qalculateexportcsvdialog.cpp:56 qalculateimportcsvdialog.cpp:80 +msgid "Delimiter:" +msgstr "分隔符:" + +#: qalculateexportcsvdialog.cpp:59 qalculateimportcsvdialog.cpp:83 +msgid "Comma" +msgstr "逗号" + +#: qalculateexportcsvdialog.cpp:60 qalculateimportcsvdialog.cpp:84 +msgid "Tabulator" +msgstr "制表符" + +#: qalculateexportcsvdialog.cpp:61 qalculateimportcsvdialog.cpp:85 +msgid "Semicolon" +msgstr "分号" + +#: qalculateexportcsvdialog.cpp:62 qalculateimportcsvdialog.cpp:86 +msgid "Space" +msgstr "空格" + +#: qalculateexportcsvdialog.cpp:63 qalculateimportcsvdialog.cpp:87 +msgid "Other" +msgstr "其它" + +#: qalculateexportcsvdialog.cpp:93 qalculateimportcsvdialog.cpp:116 +msgid "No file name entered." +msgstr "未输入文件名。" + +#: qalculateexportcsvdialog.cpp:122 qalculateimportcsvdialog.cpp:145 +msgid "No delimiter selected." +msgstr "未选择分隔符" + +#: qalculateexportcsvdialog.cpp:135 +msgid "No variable name entered." +msgstr "未输入变量名" + +#: qalculateexportcsvdialog.cpp:147 +msgid "No known variable with entered name found." +msgstr "未能找到指定名称的变量" + +#: qalculateexportcsvdialog.cpp:154 +#, c-format +msgid "" +"Could not export to file \n" +"%s" +msgstr "" +"无法导出到文件\n" +"%s" + +#: qalculateexpressionedit.cpp:146 +msgid "Disable Completion" +msgstr "停用自动完成" + +#: qalculateexpressionedit.cpp:147 +msgid "Enable Completion" +msgstr "启用自动完成" + +#. i18n: file ./qalculate_kdeui.rc line 154 +#: qalculateexpressionedit.cpp:161 qalculateresultdisplay.cpp:333 rc.cpp:48 +#, no-c-format +msgid "Meta Modes" +msgstr "元模式" + +#: qalculateexpressionedit.cpp:639 qalculatevariablesdialog.cpp:366 +msgid "a previous result" +msgstr "之前的结果" + +#: qalculateexpressionedit.cpp:645 qalculatevariablesdialog.cpp:376 +msgid "matrix" +msgstr "矩阵" + +#: qalculateexpressionedit.cpp:647 qalculatevariablesdialog.cpp:378 +msgid "vector" +msgstr "向量" + +#: qalculateexpressionedit.cpp:656 qalculatevariablesdialog.cpp:387 +msgid "positive" +msgstr "正数" + +#: qalculateexpressionedit.cpp:660 qalculatevariablesdialog.cpp:391 +msgid "non-positive" +msgstr "非正" + +#: qalculateexpressionedit.cpp:664 qalculatevariablesdialog.cpp:395 +msgid "negative" +msgstr "负数" + +#: qalculateexpressionedit.cpp:668 qalculatevariablesdialog.cpp:399 +msgid "non-negative" +msgstr "非负" + +#: qalculateexpressionedit.cpp:672 qalculatevariablesdialog.cpp:403 +msgid "non-zero" +msgstr "非零" + +#: qalculateexpressionedit.cpp:680 qalculatevariablesdialog.cpp:412 +msgid "integer" +msgstr "整数" + +#: qalculateexpressionedit.cpp:684 qalculatevariablesdialog.cpp:416 +msgid "rational" +msgstr "有理数" + +#: qalculateexpressionedit.cpp:688 qalculatevariablesdialog.cpp:420 +msgid "real" +msgstr "实数" + +#: qalculateexpressionedit.cpp:692 qalculatevariablesdialog.cpp:424 +msgid "complex" +msgstr "复数" + +#: qalculateexpressionedit.cpp:700 qalculatevariablesdialog.cpp:432 +msgid "(not matrix)" +msgstr "(非矩阵)" + +#: qalculateexpressionedit.cpp:705 qalculatevariablesdialog.cpp:438 +msgid "unknown" +msgstr "未知" + +#: qalculateexpressionedit.cpp:707 qalculatevariablesdialog.cpp:440 +msgid "default assumptions" +msgstr "缺省假设" + +#: qalculatefunctionsdialog.cpp:47 +msgid "Functions" +msgstr "函数" + +#: qalculatefunctionsdialog.cpp:59 +msgid "Function Name" +msgstr "函数名" + +#: qalculatefunctionsdialog.cpp:75 qalculatefunctionsdialog.cpp:313 +#: qalculateunitsdialog.cpp:99 qalculateunitsdialog.cpp:352 +#: qalculatevariablesdialog.cpp:74 qalculatevariablesdialog.cpp:349 +msgid "Deactivate" +msgstr "停止" + +#: qalculatefunctionsdialog.cpp:174 qalculatefunctionsdialog.cpp:175 +#: qalculatefunctionsdialog.cpp:176 qalculatefunctionsdialog.cpp:234 +#: qalculatefunctionsdialog.cpp:260 qalculatefunctionsdialog.cpp:283 +#: qalculatefunctionsdialog.cpp:509 qalculateunitsdialog.cpp:206 +#: qalculateunitsdialog.cpp:207 qalculateunitsdialog.cpp:208 +#: qalculateunitsdialog.cpp:271 qalculateunitsdialog.cpp:297 +#: qalculateunitsdialog.cpp:320 qalculateunitsdialog.cpp:420 +#: qalculatevariablesdialog.cpp:174 qalculatevariablesdialog.cpp:175 +#: qalculatevariablesdialog.cpp:176 qalculatevariablesdialog.cpp:256 +#: qalculatevariablesdialog.cpp:282 qalculatevariablesdialog.cpp:320 +#: qalculatevariablesdialog.cpp:466 +msgid "Inactive" +msgstr "不活动的" + +#: qalculatefunctionsdialog.cpp:315 qalculateunitsdialog.cpp:354 +#: qalculatevariablesdialog.cpp:351 +msgid "Activate" +msgstr "激活" + +#: qalculatefunctionsdialog.cpp:367 qalculateresultdisplay.cpp:148 +#, c-format +msgid "" +"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." +msgstr "" +"为给定的对象和属性从数据集%s中提取数据。如果\"信息\"作为属性被输入, " +"将会弹出一个对话框显示对象的全部属性。" + +#: qalculatefunctionsdialog.cpp:391 +msgid "Arguments" +msgstr "自变量" + +#: qalculatefunctionsdialog.cpp:412 qalculateinsertfunctiondialog.cpp:194 +#: qalculateinsertfunctiondialog.cpp:227 +msgid "optional" +msgstr "可选的" + +#: qalculatefunctionsdialog.cpp:416 +msgid "default: " +msgstr "缺省:" + +#: qalculatefunctionsdialog.cpp:426 +msgid "Requirement" +msgstr "要求" + +#: qalculateimportcsvdialog.cpp:39 qalculateimportcsvdialog.cpp:46 +msgid "Import CSV File" +msgstr "导入CSV文件" + +#: qalculateimportcsvdialog.cpp:48 +msgid "Import as:" +msgstr "导入为:" + +#: qalculateimportcsvdialog.cpp:71 +msgid "First row:" +msgstr "第一行:" + +#: qalculateimportcsvdialog.cpp:77 +msgid "Includes headings" +msgstr "包括标题" + +#: qalculateimportcsvdialog.cpp:149 +msgid "An error occured when importing the CSV file." +msgstr "导入CSV文件时出错" + +#: qalculateinsertfunctiondialog.cpp:50 qalculateinsertfunctiondialog.cpp:57 +msgid "Execute" +msgstr "执行" + +#: qalculateinsertfunctiondialog.cpp:93 +msgid "Argument" +msgstr "自变量" + +#: qalculateinsertfunctiondialog.cpp:152 +msgid "True" +msgstr "真" + +#: qalculateinsertfunctiondialog.cpp:153 +msgid "False" +msgstr "假" + +#: qalculateinsertfunctiondialog.cpp:184 +msgid "Info" +msgstr "信息" + +#: qalculateinsertmatrixvectordialog.cpp:71 +msgid "Insert Selection" +msgstr "插入所选内容" + +#: qalculateinsertmatrixvectordialog.cpp:293 +msgid "Vector Result" +msgstr "向量结果" + +#: qalculateinsertmatrixvectordialog.cpp:295 +msgid "Matrix Result" +msgstr "矩阵结果" + +#: qalculateperiodictabledialog.cpp:195 +msgid "Element Data" +msgstr "元素数据" + +#: qalculateperiodictabledialog.cpp:221 +msgid "Classification" +msgstr "分类" + +#: qalculateperiodictabledialog.cpp:224 +msgid "Alkali Metal" +msgstr "碱金属" + +#: qalculateperiodictabledialog.cpp:225 +msgid "Alkaline-Earth Metal" +msgstr "碱土金属" + +#: qalculateperiodictabledialog.cpp:226 +msgid "Lanthanide" +msgstr "镧系元素" + +#: qalculateperiodictabledialog.cpp:227 +msgid "Actinide" +msgstr "锕系元素" + +#: qalculateperiodictabledialog.cpp:228 +msgid "Transition Metal" +msgstr "过渡金属元素" + +#: qalculateperiodictabledialog.cpp:229 +msgid "Metal" +msgstr "金属" + +#: qalculateperiodictabledialog.cpp:230 +msgid "Metalloid" +msgstr "半金属元素" + +#: qalculateperiodictabledialog.cpp:231 +msgid "Non-Metal" +msgstr "非金属" + +#: qalculateperiodictabledialog.cpp:232 +msgid "Halogen" +msgstr "卤素" + +#: qalculateperiodictabledialog.cpp:233 +msgid "Noble Gas" +msgstr "惰性气体" + +#: qalculateperiodictabledialog.cpp:234 +msgid "Transactinide" +msgstr "锕系后元素" + +#: qalculateplotdialog.cpp:64 +msgid "Plot" +msgstr "绘图" + +#: qalculateplotdialog.cpp:82 +msgid "Data" +msgstr "数据" + +#: qalculateplotdialog.cpp:83 +msgid "Function Range" +msgstr "函数范围" + +#: qalculateplotdialog.cpp:101 +msgid "Vector/matrix" +msgstr "向量/矩阵" + +#: qalculateplotdialog.cpp:104 +msgid "Paired matrix" +msgstr "" + +#: qalculateplotdialog.cpp:107 +msgid "Rows" +msgstr "行" + +#: qalculateplotdialog.cpp:109 +msgid "X variable:" +msgstr "X轴变量" + +#: qalculateplotdialog.cpp:113 +msgid "Style:" +msgstr "样式:" + +#: qalculateplotdialog.cpp:115 +msgid "Line" +msgstr "线条" + +#: qalculateplotdialog.cpp:116 +msgid "Points" +msgstr "点" + +#: qalculateplotdialog.cpp:117 +msgid "Line with points" +msgstr "点和线" + +#: qalculateplotdialog.cpp:118 +msgid "Boxes/bars" +msgstr "箱形图/柱状图" + +#: qalculateplotdialog.cpp:119 +msgid "Histogram" +msgstr "直方图" + +#: qalculateplotdialog.cpp:120 +msgid "Steps" +msgstr "步骤" + +#: qalculateplotdialog.cpp:121 +msgid "Candlesticks" +msgstr "" + +#: qalculateplotdialog.cpp:122 +msgid "Dots" +msgstr "" + +#: qalculateplotdialog.cpp:124 +msgid "Smoothing:" +msgstr "平滑" + +#: qalculateplotdialog.cpp:127 +msgid "Monotonic" +msgstr "单调的" + +#: qalculateplotdialog.cpp:128 +msgid "Natural cubic splines" +msgstr "自然三次样条曲线" + +#: qalculateplotdialog.cpp:129 +msgid "Bezier" +msgstr "贝赛尔曲线" + +#: qalculateplotdialog.cpp:130 +msgid "Bezier (monotonic)" +msgstr "贝赛尔曲线(单调的)" + +#: qalculateplotdialog.cpp:132 +msgid "Y-axis:" +msgstr "Y轴:" + +#: qalculateplotdialog.cpp:136 +msgid "Primary" +msgstr "主" + +#: qalculateplotdialog.cpp:139 +msgid "Secondary" +msgstr "从" + +#: qalculateplotdialog.cpp:171 +msgid "Sampling rate:" +msgstr "采样率:" + +#: qalculateplotdialog.cpp:176 +msgid "Step size:" +msgstr "步长:" + +#: qalculateplotdialog.cpp:194 +msgid "Display grid" +msgstr "显示网格" + +#: qalculateplotdialog.cpp:196 +msgid "Display full border" +msgstr "显示完整边界" + +#: qalculateplotdialog.cpp:199 +msgid "Logarithmic x scale:" +msgstr "对数X轴刻度" + +#: qalculateplotdialog.cpp:203 +msgid "Logarithmic y scale:" +msgstr "对数Y轴刻度" + +#: qalculateplotdialog.cpp:207 +msgid "X-axis label:" +msgstr "X轴标签" + +#: qalculateplotdialog.cpp:210 +msgid "Y-axis label:" +msgstr "Y轴标签" + +#: qalculateplotdialog.cpp:213 +msgid "Color display:" +msgstr "颜色显示:" + +#: qalculateplotdialog.cpp:217 +msgid "Color" +msgstr "彩色" + +#: qalculateplotdialog.cpp:220 +msgid "Monochrome" +msgstr "单色" + +#: qalculateplotdialog.cpp:224 +msgid "Legend placement:" +msgstr "图例布置:" + +#: qalculateplotdialog.cpp:227 +msgid "Top-left" +msgstr "左上角" + +#: qalculateplotdialog.cpp:228 +msgid "Top-right" +msgstr "右上角" + +#: qalculateplotdialog.cpp:229 +msgid "Bottom-left" +msgstr "左下角" + +#: qalculateplotdialog.cpp:230 +msgid "Bottom-right" +msgstr "右下角" + +#: qalculateplotdialog.cpp:231 +msgid "Below" +msgstr "下方" + +#: qalculateplotdialog.cpp:232 +msgid "Outside" +msgstr "外面" + +#: qalculateplotdialog.cpp:403 qalculateplotdialog.cpp:458 +#: qalculateplotdialog.cpp:506 +msgid "Empty expression." +msgstr "空白表达式。" + +#: qalculateplotdialog.cpp:472 qalculateplotdialog.cpp:519 +msgid "Empty x variable." +msgstr "空白X轴变量。" + +#: qalculateprecisiondialog.cpp:34 qalculateprecisiondialog.cpp:36 +msgid "Recalculate" +msgstr "重新计算" + +#: qalculateprecisiondialog.cpp:41 +msgid "Precision:" +msgstr "精度:" + +#: qalculatepreferencesdialog.cpp:100 +msgid "Choose..." +msgstr "选择..." + +#: qalculatepreferencesdialog.cpp:147 +msgid "Preferences" +msgstr "偏好设置" + +#: qalculatepreferencesdialog.cpp:161 +msgid "Close to system tray" +msgstr "关闭到系统托盘" + +#: qalculatepreferencesdialog.cpp:162 +msgid "If the application will reside in the system tray when the window is closed" +msgstr "当关闭窗口时,程序是否驻留到系统托盘中。" + +#: qalculatepreferencesdialog.cpp:164 +msgid "Display expression status" +msgstr "显示表达式状态" + +#: qalculatepreferencesdialog.cpp:165 +msgid "" +"If as-you-type expression status shall be displayed below the expression " +"entry" +msgstr "在您输入表达式,是否在表达式项下方实时显示表达式状态" + +#: qalculatepreferencesdialog.cpp:167 +msgid "Use icon buttons" +msgstr "使用图标按钮" + +#: qalculatepreferencesdialog.cpp:168 +msgid "" +"Use icons instead of text on the top-right buttons. The third state uses the " +"style setting for icons on buttons." +msgstr "在右上方的按钮中,使用图标代替文字说明。第三个状态为按钮使用图标的样式设置。" + +#: qalculatepreferencesdialog.cpp:171 +msgid "Update exchange rates on start" +msgstr "在启动时更新汇率。" + +#: qalculatepreferencesdialog.cpp:172 +msgid "" +"If current exchange rates shall be downloaded from the internet at program " +"start" +msgstr "在程序启动时是否自动下载最新的汇率。" + +#: qalculatepreferencesdialog.cpp:174 +msgid "Save mode on exit" +msgstr "退出时保存模式" + +#: qalculatepreferencesdialog.cpp:175 +msgid "If the mode of the calculator shall be restored" +msgstr "是否自动恢复计算器的模式" + +#: qalculatepreferencesdialog.cpp:177 +msgid "Save definitions on exit" +msgstr "在退出时保存定义" + +#: qalculatepreferencesdialog.cpp:178 +msgid "If changes to functions, units and variables shall be saved automatically" +msgstr "是否自动保存对函数、单位和变量的改动。" + +#: qalculatepreferencesdialog.cpp:180 +msgid "Use only keypad keys for RPN" +msgstr "在逆波兰范式中只使用小键盘键" + +#: qalculatepreferencesdialog.cpp:181 +msgid "" +"Use only keypad keys for RPN operations (+-*/^) and use the rest of the " +"keyboard for expression entry" +msgstr "在逆波兰范式中只使用小键盘键输入运算符(+-*/^),使用其它键作为表达式输入项。" + +#: qalculatepreferencesdialog.cpp:183 +msgid "Ignores dots in numbers" +msgstr "忽略数字中的点" + +#: qalculatepreferencesdialog.cpp:184 +msgid "" +"Allow dots, '.', to be used as thousands separator instead of as an " +"alternative to decimal sign" +msgstr "允许在数字中使用点(\".\")作为千位分隔符" + +#: qalculatepreferencesdialog.cpp:187 +msgid "Enable unicode signs" +msgstr "启用unicode符号" + +#: qalculatepreferencesdialog.cpp:188 +msgid "Disable this if you have problems with some fancy characters" +msgstr "如果某些字符无法正确显示,请关闭此项" + +#: qalculatepreferencesdialog.cpp:190 +msgid "Use lower case in numbers" +msgstr "在数字中使用小写字母" + +#: qalculatepreferencesdialog.cpp:191 +msgid "If lower case letters should be used in numbers with non-decimal base" +msgstr "在表示非十进制数字时是否应该使用小写字母" + +#: qalculatepreferencesdialog.cpp:193 +msgid "Use lower case \"e\"" +msgstr "使用小写的\"e\"" + +#: qalculatepreferencesdialog.cpp:194 +msgid "If \"e\"; shall be used instead of \"E\" in numbers" +msgstr "在数字中是否用\"e\"代替\"E\"" + +#: qalculatepreferencesdialog.cpp:196 +msgid "Alternative base prefixes" +msgstr "切换进制前缀" + +#: qalculatepreferencesdialog.cpp:197 +msgid "" +"If hexadecimal numbers shall be displayed with \"0x0\" and binary numbers " +"with \"0b00\" as prefixes" +msgstr "十六进制和二进制数是否以\"0x0\"和\"0b00\"的格式显示" + +#: qalculatepreferencesdialog.cpp:199 +msgid "Spell out logical operators" +msgstr "拼写出逻辑运算符" + +#: qalculatepreferencesdialog.cpp:200 +msgid "If logical and/or shall be displayed as \"&&\"/\"||\" or \"and\"/\"or\"" +msgstr "逻辑\"与\"/\"或\"应该被表示为\"&&\"/\"||\"还是\"and\"/\"or\"。" + +#: qalculatepreferencesdialog.cpp:203 +msgid "Multiplication sign:" +msgstr "乘号:" + +#: qalculatepreferencesdialog.cpp:215 +msgid "Division sign:" +msgstr "除号:" + +#: qalculatepreferencesdialog.cpp:230 +msgid "Custom result font" +msgstr "自定义结果色:" + +#: qalculatepreferencesdialog.cpp:234 +msgid "Custom expression font" +msgstr "自定义表达式色:" + +#: qalculatepreferencesdialog.cpp:238 +msgid "Custom status font" +msgstr "自定义状态色:" + +#: qalculatepreferencesdialog.cpp:243 +msgid "Status error color:" +msgstr "状态错误色:" + +#: qalculatepreferencesdialog.cpp:250 +msgid "Status warning color:" +msgstr "状态警告色:" + +#: qalculateresultdisplay.cpp:52 +msgid "a matrix" +msgstr "一个矩阵" + +#: qalculateresultdisplay.cpp:54 +msgid "a vector" +msgstr "一个向量" + +#: qalculateresultdisplay.cpp:57 +msgid "double-click to view/edit" +msgstr "双击以查看/编辑" + +#: qalculateresultdisplay.cpp:60 +msgid "Unknown variable" +msgstr "未知数变量" + +#: qalculateresultdisplay.cpp:72 +msgid "Prefix" +msgstr "前缀" + +#: qalculateresultdisplay.cpp:336 +msgid "Show Parsed Expression" +msgstr "显示已解析的表达式" + +#: qalculateresultdisplay.cpp:342 qalculateresultdisplay.cpp:353 +msgid "Show Object Info" +msgstr "显示对象信息" + +#: qalculateresultdisplay.cpp:348 +msgid "View/Edit Matrix" +msgstr "查看/编辑矩阵" + +#: qalculateresultdisplay.cpp:350 +msgid "View/Edit Vector" +msgstr "查看/编辑向量" + +#: qalculateresultdisplay.cpp:382 +msgid "Parsed expression:" +msgstr "已解析表达式:" + +#: qalculatesetbasedialog.cpp:33 +msgid "Result Base" +msgstr "结果进制" + +#: qalculatesetbasedialog.cpp:39 qalculatesetbasedialog.cpp:52 +msgid "Other:" +msgstr "其它:" + +#: qalculatesetbasedialog.cpp:43 +msgid "Time format" +msgstr "日期格式" + +#: qalculatesetbasedialog.cpp:44 qalculatesetbasedialog.cpp:55 +msgid "Roman numerals" +msgstr "罗马数字" + +#: qalculatesetbasedialog.cpp:46 +msgid "Expression Base" +msgstr "表达式进制" + +#: qalculateunitsdialog.cpp:54 +msgid "Units" +msgstr "单位" + +#: qalculateunitsdialog.cpp:68 +msgid "Names" +msgstr "名称" + +#: qalculateunitsdialog.cpp:69 +msgid "Base" +msgstr "进制" + +#: qalculateunitsdialog.cpp:72 +msgid "Conversion" +msgstr "换算" + +#: qalculateunitsdialog.cpp:105 +msgid "Convert Result" +msgstr "换算结果" + +#: qalculateunitsdialog.cpp:250 +msgid "Cannot delete unit as it is needed by other units." +msgstr "无法删除此单位,因为它被别的单位引用了。" + +#: qalculatevariablesdialog.cpp:51 +msgid "Variables" +msgstr "变量" + +#: qalculatevariablesdialog.cpp:60 +msgid "Variable Name" +msgstr "变量名" + +#. i18n: file ./qalculate_kdeui.rc line 5 +#: rc.cpp:6 +#, no-c-format +msgid "&New" +msgstr "新建(&N)" + +#. i18n: file ./qalculate_kdeui.rc line 37 +#: rc.cpp:12 +#, no-c-format +msgid "&Set Prefix" +msgstr "设定前缀(&S)" + +#. i18n: file ./qalculate_kdeui.rc line 39 +#: rc.cpp:15 +#, no-c-format +msgid "&Convert To Unit" +msgstr "换算成单位(&C)" + +#. i18n: file ./qalculate_kdeui.rc line 54 +#: rc.cpp:18 +#, no-c-format +msgid "&Mode" +msgstr "模式(&M)" + +#. i18n: file ./qalculate_kdeui.rc line 55 +#: rc.cpp:21 +#, no-c-format +msgid "Number Base" +msgstr "数字进制" + +#. i18n: file ./qalculate_kdeui.rc line 67 +#: rc.cpp:24 +#, no-c-format +msgid "Numerical Display" +msgstr "数字显示" + +#. i18n: file ./qalculate_kdeui.rc line 80 +#: rc.cpp:27 +#, no-c-format +msgid "Fractional Display" +msgstr "分数显示" + +#. i18n: file ./qalculate_kdeui.rc line 86 +#: rc.cpp:30 +#, no-c-format +msgid "Unit Display" +msgstr "单位显示" + +#. i18n: file ./qalculate_kdeui.rc line 96 +#: rc.cpp:33 +#, no-c-format +msgid "Angle Unit" +msgstr "角度单位" + +#. i18n: file ./qalculate_kdeui.rc line 104 +#: rc.cpp:36 +#, no-c-format +msgid "Enabled Objects" +msgstr "启用对象" + +#. i18n: file ./qalculate_kdeui.rc line 121 +#: rc.cpp:42 +#, no-c-format +msgid "Assumptions" +msgstr "假设" + +#. i18n: file ./qalculate_kdeui.rc line 137 +#: rc.cpp:45 +#, no-c-format +msgid "Algebraic Mode" +msgstr "代数模式" + +#. i18n: file ./qalculate_kdeui.rc line 161 +#: rc.cpp:51 +#, no-c-format +msgid "Fu&nctions" +msgstr "函数(&n)" + +#. i18n: file ./qalculate_kdeui.rc line 163 +#: rc.cpp:54 +#, no-c-format +msgid "&Variables" +msgstr "变量(&V)" + +#. i18n: file ./qalculate_kdeui.rc line 165 +#: rc.cpp:57 +#, no-c-format +msgid "&Units" +msgstr "单位(&U)" + diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..c5991ba --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,58 @@ +# set the include path for X, qt and KDE +INCLUDES = $(all_includes) + +# these are the headers for your project + + +# let automoc handle all of the meta source files (moc) +METASOURCES = AUTO + +messages: rc.cpp + $(EXTRACTRC) `find . -name \*.ui -o -name \*.rc` > rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/qalculate_kde.pot + +KDE_ICON = AUTO + +######################################################################### +# APPLICATION SECTION +######################################################################### +# this is the program that gets installed. it's name is used for all +# of the other Makefile.am variables +bin_PROGRAMS = qalculate-kde + +# the application source, library search path, and link libraries +qalculate_kde_SOURCES = buttonwithindexsignal.cpp kqalculate.cpp \ + main.cpp preferences.cpp qalculatebuttonwithdata.cpp qalculateconvertnumberbasesdialog.cpp \ + qalculateconvertunitsdialog.cpp qalculatedatasetsdialog.cpp qalculatedecimalsdialog.cpp qalculateeditdataobjectdialog.cpp \ + qalculateeditdatasetdialog.cpp qalculateeditfunctiondialog.cpp qalculateeditmatrixvectordialog.cpp qalculateeditnamesdialog.cpp \ + qalculateeditunitdialog.cpp qalculateeditunknownvariabledialog.cpp qalculateeditvariabledialog.cpp qalculateexportcsvdialog.cpp \ + qalculateexpressionedit.cpp qalculatefunctionsdialog.cpp qalculateimportcsvdialog.cpp qalculateinsertfunctiondialog.cpp \ + qalculateinsertmatrixvectordialog.cpp qalculate_kde_utils.cpp qalculateperiodictabledialog.cpp qalculateplotdialog.cpp \ + qalculateprecisiondialog.cpp qalculatepreferencesdialog.cpp qalculatesetbasedialog.cpp \ + qalculateunitsdialog.cpp qalculatevariablesdialog.cpp qalculateresultdisplay.cpp + +qalculate_kde_LDFLAGS = $(KDE_RPATH) $(all_libraries) +qalculate_kde_LDADD = $(LIB_KDEUI) $(LIB_KIO) + +# this is where the desktop file will go +shelldesktopdir = $(xdg_appsdir) +shelldesktop_DATA = qalculate_kde.desktop + +# this is where the shell's XML-GUI resource file goes +shellrcdir = $(kde_datadir)/qalculate_kde +shellrc_DATA = qalculate_kdeui.rc + + +noinst_HEADERS = preferences.h qalculateinsertfunctiondialog.h qalculateinsertmatrixvectordialog.h \ + buttonwithindexsignal.h qalculateexpressionedit.h qalculateconvertnumberbasesdialog.h \ + qalculatebuttonwithdata.h qalculatesetbasedialog.h \ + qalculatevariablesdialog.h qalculatefunctionsdialog.h qalculateunitsdialog.h \ + qalculateeditunknownvariabledialog.h qalculatedecimalsdialog.h qalculateconvertunitsdialog.h \ + qalculateprecisiondialog.h qalculateeditunitdialog.h qalculateeditnamesdialog.h \ + qalculateeditfunctiondialog.h qalculateplotdialog.h qalculateimportcsvdialog.h \ + qalculateexportcsvdialog.h qalculatepreferencesdialog.h qalculateeditmatrixvectordialog.h \ + qalculatedatasetsdialog.h qalculateeditdatasetdialog.h qalculateeditdataobjectdialog.h \ + qalculateresultdisplay.h + +install-exec-local: + cd $(DESTDIR)$(bindir) && rm -f qalculate; $(LN_S) qalculate-kde qalculate diff --git a/src/buttonwithindexsignal.cpp b/src/buttonwithindexsignal.cpp new file mode 100644 index 0000000..34fe66e --- /dev/null +++ b/src/buttonwithindexsignal.cpp @@ -0,0 +1,31 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "buttonwithindexsignal.h" + +ButtonWithIndexSignal::ButtonWithIndexSignal(const QString & text, int index, QWidget *parent, const char *name) : QPushButton(text, parent, name) { + i = index; + connect(this, SIGNAL(clicked()), this, SLOT(emitClickedWithIndex())); +} +ButtonWithIndexSignal::~ButtonWithIndexSignal() {} +void ButtonWithIndexSignal::emitClickedWithIndex() { + emit clickedWithIndex(i); +} + +#include "buttonwithindexsignal.moc" diff --git a/src/buttonwithindexsignal.h b/src/buttonwithindexsignal.h new file mode 100644 index 0000000..0c0fcfe --- /dev/null +++ b/src/buttonwithindexsignal.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef BUTTONWITHINDEXSIGNAL_H +#define BUTTONWITHINDEXSIGNAL_H + +#include + +class ButtonWithIndexSignal : public QPushButton { + Q_OBJECT + +public: + ButtonWithIndexSignal(const QString & text, int index, QWidget *parent = 0, const char *name = 0); + virtual ~ButtonWithIndexSignal(); + int i; +public slots: + void emitClickedWithIndex(); +signals: + void clickedWithIndex(int); + +}; + +#endif diff --git a/src/hi128-app-qalculate_kde.png b/src/hi128-app-qalculate_kde.png new file mode 100644 index 0000000000000000000000000000000000000000..133985cb6d642320a64c0745d3d1c9f75a479ca7 GIT binary patch literal 13323 zcmV+mH1x}fP)S5C*uGB02y>e zSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{03ZNKL_t(|+U;F;nB3I0Kj*4U z+upppwy_O1*am~a5WrxnZAz#PHK9B@BtRgclk!3Wgce#t3nU?w7;u2_sCH-u*Cj#Ur*CIQ+8Igb+*5w1A?&yt=6R1H$FZB=$wFSU zEgb)k-qanK=pv!z*ZGcxF@sE0CcV!09{wAcLEXU!A4X^d0Fvi5=3xrRv(m$MdkgRX zqZvWnfmVAM!O0f(FoqDnJ0J0FVdw8@$Y=lY%z!({|xt8^Vi(R;68$UMm2gjL~;1J|epBpdngqeFCEK2x>8%=rJ9Y7y<#q zHZxf;(phGv(#%M$F*h~L%zU}_b7M)nKw!(=#n%XWoFZ6+VoMYXk-ibICb<|zjEfDifohB{P8Qv51)LvZQ3_3 zBV-CNg1xgb0d6DW^Hndd_9y^E&nlic{L<2suddZ9CjbKkU@p0XsvHYEQU4s~e1-5& z9--y$2)tpOg>rwxJ#VwsI{VKZuRri~$6HGPARWR8Rvu~aU&jDpMxH3@qW};qC5hrk z23&vs*vN8U-dl6^gG2P%$pldaS4SfON6e$c2!O7N zMn`OWpNpd1J%)mP;GHh~pZ6Q?_i{!MKlhFacjK84h(HjP0cz#AGfIv=st9At{*{^E z+zt47d*UtIg#l!J9|3?EC;lS?t~>R#;v?^hDv=sz)uKxybXTz}j?w2Q4_as@m697_@O0Ysu#QvlW+a3%cihd<*<=3f|6)z0>%{^6W`N6Vz z$4$PV>Bsdm1U?f9Kou~%YSj(tYNaV%t+#XyR9my~OLjbMI*3=}`^)@S( z*kD$~8_bGWlT}%~$*NaOhy*w)RPpDsC-V$O|MMoRea`pS{o*HUt<9|fkQBTH(Kzg` zVc64fH`^NNgMB1H!gPKN0OB=DdHJ+m?zpd7DLW{49dRAZ^4R;LMaaO?AlouRU(`4z zwxVUf;&m9)Ohr*_M8b%o*p8~kz|Aw)FSIEojM+#jC3eQ&I={48=mxPz=#P`GQ>Cc0;ibM8D|japEUbP>N>^d+6R;z4CDJ zAvp#X^YIqU^C%dA6@ko#@5JY`s5T*lIm9OnNjL*A z+m!;$Mrv8arWT=;63a9d%Q6+qG*mO2RR_J*y4RpjQU~iPmhhhph7h0S^%ongmX9W` zxay}C&<=?SEP)AFi0P9LDi@=lG6NKfWOj=Qu#fb%phV2$buLHGS5}4(JICc)oNGG=$f-i647$xP}cWK2zJ6<=(zhj zDnRI*F;G$q-S#-tt&{*c7kp0nvAZ8vdhjnDxE%vQ7vwIOXP^l-ARtf$=f$H-SYP9PR&;tCgK765t(qu@~Bv8CgG@l|H|if3Binx98B zhk3vOb-Hl(sjGaEBl)DF{|W%3mYg*da+6rLxRI@l?up_*s)CaEVfAT0S5Qd=+1p)5 znCq`I1OS3SRWKKQuk^Le6RQ@*;)!fD7B}>0%#1{1rXG!0niip&7IDPCs@ke6{)xm0 zd2duWS9QNb({;+fSC2-lNHk_f;|U`giyP5c%xE27xnlkg%3h{AWPB76y+zM_-USBe z#~}!SMwIvutH1Yi6_kX#ICS?}DNs1C(UYhF5DJ(Fnt2Z|=qE%3brEJX_6Y+(9-Kb{ z0I?^B+;T>RTC%qX&60e!Eqa6pC+f$Ro>2UD>-dTl(OArg#NviSh?uEIqgEKfSoT>vrSqGDj_4bMs}GIMY&^VTDJOm;8Z-4s#8TZAstBuHCVEe~SN`9CL~wsg zk3=jj61AeSxDkuTvuy`etXgqo{5}7%q7Y|5U#+3JXf$T%k*LXu&j})n_}&m*-v0XFougiR_K!zx-nf1+wJfc)qGI#dgAV)rw#TQw zt7#D`dJ;Bc$QZ+o$5nk@ym3>_fQ80B0Quoz(JlZ)&_Id*bifa;eWQKWbs?5IHx9#7 z<+wCK^x~F06@nX7=wm2Kh(f2Ff zkGKY3A>#LT#mn2TuR8y*$L_f0vbL6{>OIFD_~`+MPy8TJT-yG@8!sQ1qY@&HU7$yz zrXGo!OV6zQC{u#1;=N%YAsv0sfcTzIytA@Jp{ct*IyK>)%$ z2?XKk@qOwApyaE1tN*OZ$(IU7ae>H=zx){iw&aB38CVfd>5-_ZM`Na{IX-?E@%tiT zHS?`kYu|q9*;A_P2Cn+k^v@ottf@8lv5%+!-++KOp{lmcC~CG%sUEQ?rNl0!>BXm% zzO(nUZD$}u;w_&56yS%X{r8AxR!+L)(Z;`D8xknW4-FGBp~c5gn1EC=WZVPk5#f7l z1IWI={==Hn_N>(_CwQS)aTWMhl3)Zn?^}jxi`(`uTdhZ;rmpLjrs-7Eb*j2d|@o1A~mt^W{-4*+oJNx^(`$y#WAb&3Jv( z?04VXgCC!K>i55%H0A8|{5Ne%kr2W_Rc+h0QPXuwDJ7a7v2@EaSDaWjyW*jyJrv5c z+@}@9I~aNhCw{N;sPiA$?By1!QhWfzo_sLy6qb78#kR4(7y$C2Rr@7IR@Q3Ohlw}N zg_W0O$M`iePj_wJGcwN{lxT|!xITCD`XlM##Xml@&#dXMAIsm*{^y&M#p6@XzhZ7) zsFbS$O`}wgSe9ujsoHo)!D>Mm1fxR!=PX z(k5v6+73As5zarbjGARcuAkZ0uuKPuyO3;(_7g2jBw$ z09_qzRpSTX1I|wFU;53L#rg08&IIT}(2A$mA2=KJJWjUm3C2*v{_4 z$f6WbRh6!rQ1peEPL2XHh@w;!Y~f_a3j~l{Po4oB zS+@U##~WV$MvwqhG6XT`R-%uj3Pv_y_bT9e%K(Kcc(ozXx`X&d_&BIwq%agBeaU)(o&o*n^1)b9|YsJRh8^!2|803m`I$IkZMqD_jT*pB{JY>v72hvgr()zlBpo^$05 ze>1Y#_>WJYeEnr79CF5wPoH$sNqg7-^u<3uc+Qq20M9sb3|D9G92RZPCa~R47{MIe zgWEvFeIA4;>gDyPeJ2kj9Qybf@xRLtv#_A;)ejONw3dH(eDL0gp7$&1JE_RhecxH5 zY*19q6aQWcR}T!oLaV#G+r>Bh>YM7ife$_RhkK4$_~mE&xxt{u!@oP_jqa!c3Qqc& zBf*^e>8epSMpx5P4*@|8tXK}+iZ?nuK4=U8OwSV;lpZDKH~|4up&u9k3rGN^QY#$+ zUR5=E$(=ccxEvxxfQ~`hdPPxeg6L)Q^wjF#S{s0GC!c%is*}&X^zoi}5uzHP)FeC` zSy2?bW1zOaat$4cu5T`8K*uQrkRL{aRP5z+O-W@n^EB)s-etX^`_ zK?EpOi$*|hucM#^A;#4i^Dq`U7LEOg1m;M9qszZj9aXjRpw8#&Pi*4AJb2hv!0OyZ zZ{-h->(ZX8fbG4Bc7P8MDR$>zz13FH3LroHiE%&-5g2iahzJoyuQ;M~TovTc4hm2j z3Fhj05_G=$(+2RQz|j>4?C!z69;b^Z=Q<|YV$w!5l@j7q@o>w(r^MeDtGg$503u<8 zC^pelY9z2N+6h%24vKyus^|`ilJn?_19$(ReeRk(P_Xcdc+!L?hX!&*w}Axk#D8t1 zs!qoK14tmZRJk-jfOH9IMGR*0?o2B`uO#5$5E7OyRa!k548_$ddP5{oh+G$~sx24~ zAOfn&MLjYvrxFPUQP)0Z01OKTm1!k4DA(pgu)>;2?oXzSv=V|$GyubJ_Z^z((lz=O zNyrF6mMO(nAUq?=B^UuOsZ(6he9@F@MKy(7Km-&#X+IMP1qsY@Qmy+B3Pu3HVkKTJ z`W=2bUJw%(jZ>qDBs~d$!AhQ;al=44nj-;>VkPOM`?(pyJcplW^`IXe;>LTilBj|3 zcDF(>$PWbZka_?m-bz2PCpG{A0Ew&78ret90Ruhr)VX-0L`f3Y^55BsANr6GS+RPqQ_GCJ^zY?24;;E{8UWzRDMy{M^qVjD>gs5( z&?AxbZllM1^Q%Yy_Ugc)yQVGE#B+`qb4k;t4fW|{vP9GM^w1Hb7GHPQBmXySasAKK-bo8U?^${~WPB zOQ4;K^Le&JO(EiTTlJ=q)%Q8@(0PX)ck*=k*rs)>>reRpg>ODI?Vq<_d;3FwY*@Eu z;I(HRa~?mw`(9(0UHQvI2$sp)i?&4=a5C|%fg5;Aji_uFv!+=o< z*#9_y_ZJE1;C9hs0n^3r_ywN3;#{~LAy#iL?x}nJ_oV&CA3p0RcRoC4308o(V0y{`o?O3QB@8;P-R72X+3tRZbr=^?L ztsZ{nW!Jn705D>&v7MLSa{Cjd6_x4!Aij~!k}FR=^4wUwDEaFrUI^F<6Hhs7?ciNU z+`VYtXVuUB;oj5kyXi+q-1hj?e~RZ=I#MnLk-06e5CZiwj0r^@41fTM6p*%_ROJaE z3`AFwxfRKdH_+b`$FVm6`w$qgY`*8rRe+;5g!qDhuzF20k!=$RzyN^RXlDUfOf2*E+(4nF z8wf4hiD`SkV+*}{3K@c}O`A&q09G$uShKZ6p7HYE1_A)ATC%VT0ATjJZ`PHTS7s+o zIeYyTCm(kDswE5dxaIz*o-mB8viR#SN&o;xjNZHR)xSPI?DJ1P7gY`4xY zKl!lswP*i${GegO7nfC5o0)Xds|-@Iw#wYhU1W0qL7|l``U#yBsR4!BxgbjYh}$UM^po)b06)9rj2i>)=f9WVTwGe7UGVvwJwJN;wTY%-M5D1- z*KVWt{^n;7{@KeO@> z7@n$UVqaYm5eynDT8c)+JGB`_WedW`vP=~KpmF26+O1`PLSf`W#|94Fb^W9%XFnvW z3+LJ_Vw%~2$X8Q#6fj@USrCc^0sPD%I}3%Tk_plRn43=kz72scN3eb_3<-3eGQsK) zSG*sb@F#A7(8h!zLbTJ4Gse*FfeU9-O9cREZ)vWT^(_Fv)u&B7Y5V|u;Ld9=9xore zVB)xQ#t*;;{&3q3`}Q}=$QwvRJM9<N4{<$+@)2w*U)6AE_rLYG1;&@5Zb#o(=J zwiN@|X_{$5p=Fv6ZUoz=iB)oXmz`j)3gAr}MSCFh!iY+pbExv^hcl|><99v%>Kj!9 z>esya!qcbBn(>BbCp`SW*X_6X>(BS!bKF7y`q3}${-VzbE?hIS8S?wmyJ!)2+R@A6 z#hjR#C>@eC(+Gu{I(kMU$q5>Z^_TsL1m^UjP0~yw1Zv<==)WJ#ismtFJ!vPH+pg7S z-LnN$P4$44uRoieqXuG$BKq@(|MFKPgxz`VMdu|uJCu3<{w4$=%?!W%y z<^Ejx;=M4&Fp^?%@T8tlxf7UwfPuY>rW>K)&?%|cf@oW~AkkI=fjyT1omO(Q->?XT zR40_gzkl=5q+QHdkmw>4aNQ~qIK^MDS+;mU*o7T%_@t)OF8tApEsYI>Zu*~7PyE#n z&pC%$mU7*1A9=dGs>bL~;s@R{8>30PBnO(s;NS`r77Zdm7fo)4U^ma4mI}cpl_;nM z^jg!ge#!?39k<$Ib~JEQ!b=G!LS`TfiarJa@lL3ql=|&ix#e8o$BRqKJO*goxIQly zaP@7!n>+8{AMY{u-Lw#_iw$;wg4jt&}dOt1s} zHu=p)8&?5gT|@&bUhJ_90Dk4QH|?zdC4db8baB_JHI5-8b;95zCsH0f0z{LnoH2%s z+0Nb#6;M`H)4^Z2H8)liI(NcxCx7AC4GKNw{L8C-hMqvFe!`eJ!sjH(j-+8N-E=oM}&~ML*#^N1}G5GlTFjHbjK4Iy8EbB0Te3AcVRbOaO(Hd$z;i8 zH{bru5hqM}bJM!j!*9L#w8{NNe9;4-loFd#Qn|{g3v2dpp&E?@|bJ?OAz z{!pl8MZzxfS3f%U@YPEf?RmiA6W=@YvTK(9>e1)ls~bFY>8$B*On&Lfhlclu{^!@t z@4>byDce8?0v71b>H%fUYw^-zb}WTp6X{%cP@IS+coE`HZEbM8r#65M09He$Wsw;0 z@X)^;PW7$f;ucyTW(el{(US5CGhS5O#<2kT`1HR&KWN6we>PL*4t`#reP>C_?H_G0uRnD1 zi4F1vUvcXl^FC={*G!!@0G`|c0260PL_t)w=!vZ@I^ox3+rHWoB$-mXFte+|Pz?Yz zqImX=KG$Pnkg>Ckk1l(0DdbM~U|}{ufRhO3+6LRe3y|m2SPj|cPm#Mgl7S<4%HkYS zv(_3OrUvp!fchcBHUj_hfhsH$r02!yv8Mayun-7*!H%tp$Z*-+UccPfD)2n-6zGxOV5%!b_gK1@ag zQG{Ai7;x>u?(%%wZ2$yu26%kwi?eL7v&=O@m}iu@`RgK>!TZ|Ts15ldvzKKWs$m!^ zb!`D^S)tc4YU}|`004RC#BBnw@gDF@?~bU!ax%%f0l1Tfq@OlIVd!TZwq|6bG<51ANuGq;*4j^GuI3U0vi!0I^^}$d0XF zY3*$qhDx1rZAzFi$RGTe1ID)^5<8YibZsxu!e{f1(ihH6=sQn$j|M{bHOrf>OP zkPi*7Pi_8SVf%`X0umq~{+U>29!R+p0!`b<3t*xR008EPo9F&Rv_zRC?oetJg$NMI zV0rEQ^sc61sLo0<6~4M;TR@LQ>}WjRQCwQywmnqwc`yd7abL{Km=JdflQg~d*IzyM8Tj)8wqO9FrvexXL#c!zQeKp?m&w6B5gxW| z2Uv_|7j>+7g?S<$gVrj+T!4rmBr-T)moGA-jci6U3_~?tRbWw*tX;7*e%n>&UHj@^ zA0M`9?doW%tF!cg!zV4>Uc{%CMJ&TmOw&*d!%&TEMyvlaxkqs))Jg%nT;`YRe&@F? zdqr6Ng~WdV31sNk1co-A*hWYoK<>24>`im;f6=rpUqlDQ6-W(Z{8X|b3(N!U&P>e6 zW;D~ts-~+7GU=2G0NAi$UCCY7UpBFJ@Q{@~tp)6>kS}#}|4h?VoXMgYji$1ZVGHPZ zkP|#4PLSILW^J?OhPn5>1i@Ltg~q&kJ>fAR5d@@B%);vVc={eo08tHa1~8U)u5JIi zZOL=Fb8~!`B?r?6fCwd}dw!UnU}Q6zk1UlPk-|t&pdHlbHk>p z`~UXVpSK6`9l*yVmSHMpHluO|81+%|kZ2alawJ=zTNVhVa?WS-S{FaFHo2)&k^o_O z0KUO3L&IA@nZ z%_bOA^G$M9^FGQFLU`*qWH&1AG}Casx< zp>P6(xrhCw^DWof_lTd(s@Y6N%cPPK(wr_HImeugNYG1)<%OSKY8C_rI&f()yK&wV z8&i!PkUL7A=2`s|04%ZUilID1Fh>Oy1eN-d0dl+n0LWZ8^VVstM*BRcr=1kU;v-H_ z&KpFCfLc6uM)G*OJ(b9&QvoKR)Xa$-+LU5nFoO6!qQNH;-^ipjBb(7^S30`yyXljn zCYJaO@rC;cObzu{DFcM2OzYEs zLBI+)0eiv>^8W-vyOu>LHHneQs?KkxwM-_hXS%wg`@EYvwzv!H!~l$AnUfsAMoa{u zjAkF4|Lh&$jE~RcasOofZ3zp@dv-bT2J|Pfx^7^$fNha?>&;4%r-$g^%*IUsK=I!v zJ$U)ps!^Ar&_;xzSS8?BwDBpU{C#VJF8kuRqIZ;%cq$T&8IhR14JdP~ZWv?88|2$IC0-vIfso?4`F2Vv zVT_^ergBkg63a3bGm}+Ck)KH?BX)Z_vEPi$i4|?QD+gl4rWZla28FJm4t*NZEwjJ- z)@66vz`9(*hpo^;&o)fba$;wMT_n8OQ$tYc13M}Z^tBjeUp6oL^n{^@AFU}`i8wRI zcM+M?;>1VHA{HsFTWSpNjL_E366oT@vu%fHzyKMeNNq|OIG;1yAu2GxQb*jK1P+Jb zwoToDj-i-YL(OI~nq_9yY&N60hNxb=GC6SE2iYk_DXbOm5&^uvzg#>Af?n=APFb0? z7k+Td)f-cdEqTPh?5>4Q1Pn2_O^Fc<;j^&t@)i+7r4NXnBMmmBHk*{$UmY}H@8by) z4MW?f1&I$rh*JfO)~>fl>aB*}SYbC(w83^)FSSg?VFugXDY0!zY-S^+7U5~ye7D^5 zo#2zHSca*Xrl~k6WL7n@SuK-J=|(24n_a2cZvRdmF!C#Uj7BjoDm*bK!w+x;BXa-% zmTjf(`|9bd-dZzrB><#CjKA)>Xttb#Au)m}yf2(v*iRAw3w+MzHqLJwTwK3uWcje8 z5Q!4(nJYrX+4`s>-AryM(#7)Jh7??Mj#L(16p!{XP_M%a3sby{=Q=R zO?Q9!)Te^Z&xVNRu$75<&{rn>FBK$$OmqstDx<9;Vo&~Go+uUpfG7aO0U&YTAvaDu zdDu~R5>T|@F9ty&5GTr`TYdFE5{d(+#uleb*&^O3=~W zHOj(T^KFSv`Fwu1tr!3#CeQ>Xhyg&+eTUpQ@swSUzJmbKShzWz+m#^XJY)biFuSV= zHnmlfHBI$oO-rr1+180g6sHxv;~6-PvF+9$FlM7oDM8a#%Nnez>J9eb@@9LN;x4Es z%&AagKCa^p=8#jaJ-%eYmVY+0%~w~vd-HX(?s^vhx&*zS6-0M;^)hxt)rJwd$Heao z1^~&835=E%m>_ZI!9O{C%5IZ?qY<^(tDKd_%n9uk-Tt`Z5NhVPOBEP}0b_;+UD+74 znHr|40tQvl1OQMd(})GSX0b>#4Q0B4B?NgNXSwl;>vIRbU;K3eeHEHwnYP*a_hs+g zdduwlX9{A!5ai2xU|V%p0_ug_t11ncxSzpE%;iaTniHq$h?23E&q@ijhzz zU7|RToF5a|BWGSY2;VCwPWVJ;!fZp|uV?;%7ylR0?bz*p(q*Jp-tpPv*H2yg#!^Y= z_mudUN22Cq1ePaZr`r&4Uo(J=2Z&6dxso6X0P)?+hE@J~(w+ZXpQt_}fS>S3&sfe> zOcuiQ80s})`1-*79|V6xNW6p`H6J*>G1>Ux#qZww%LOgVn+1KJ5iE4t1B+aKcJiF2 zd~RZ(ZnHpkQNQ8<-HjbE0I-`gZP`C9nD+jtirqF2E~(pFRg{=FAX#d8f@vW^SzBis% zkfOTqn$H{-XATnR2J82?1jwfjh;T!?Xdv!CV6U2cC){|=kmCB|op}i2d^}-PnxquG z?pcU|z64AX zI$sGPz6QC&CBwqBF-&h-LY%;yI{=eBaXSKHc>qRc?&I>nG23c z?Z)vO{66T4GM;0{m|#yh&flhFB0N_SBF+|w z1#D3QVLyt03<(}7l5HT~Z1mDGXYO(CsFN?KPt+Vi2+?{j(0Ztx3Va`9%-WdTJoEWQ zum9-}^PXEM5j`vE`mpjY*3D;x(#nqlKy2kj@2%?IEi=ecbLGgt9D9Uhgmx<`*q;oL z6DN=uK^AqK8T9=J>{a#S{m!2}x^npBifHNHk^|uS=$Hd0g@Z_t$AAtw&KPUWv@clL zvf}MO%zO5oPd0qfB&~EKkEpc^xMSUktn%mKxy>stes6J@PZYd2=ku&(tQz^3VDI9_W2T}Hn5NxMDNO!Ndz#!^v&j4ZGmL1~0SVG8C6)oLYmd!}L zvTVjm0C))iw8=vb9dOhx2aT*vRPRz5Egf7MDIOTtV%3$g@}V5ZakA^s_w5NlYpQK^ z(#kZpXFJ!oW;)ic?`l~4@%p)oUtjV520@g|gtjE2Q$e@(cGVYxeMR@#WeZ^dmna2A zqtyXEH7GQPIM4NMD+UOY2145mK=;8a!pc)6<52+sb^7X$lhap!yjH*#5&%%N>e3Hh zU=WzxWjmWeGJcRfnE>H&5VRFPtnX$FCgtUh?6i$T`L5zKp%+wLLLDT z`~L9ua>1ey<{3taq0A(H#&#qI2zzj{`Nr)7lE-*71!i#~kSHZ<>t|r48gk@3zmpLlnltxWyq}e1aE>kgfOQcO(YL_rOJ7w;?!)H7N2hg!uy#JfxAP z{&)5&lGeZXj{&jof!tzIk|!B3-vZhx86fN?!cfJafk-gqKLT}HiWEGNN4D<>#P_cw zkc22rXu)7fnlP2M$Jf83GeB6RjL2Al<2FggZm^LtgrJX>;CeDa{BJL@9}MpXdN50w z3`}B<{KcVLWQZM|0m2|tF+>^#FJK}JX%0;A_OJmCHHYQT+uLdN=kLhMD}R`XYvj5% zZZSH8UKEDz=nRlAq9_NEA{;smWbhzJ89kv4kk13aZNLm+S&<$*E~39VGlIRA{LHIH zhQdW5Y-g1Kp~(`fuAaFPL+=hHweP=QebvlYWw2<-Lx&A=ADq<7W4lO#U|}e6XEAtz zYauyJC>KWpKnSs+2NA%XRR#Dc8HmuR50`l(YZ1hi;g4WNA@9(6Jft`9X+NrgKw&6g zFmHhg>Cu6?fld~5uS&yq76y>m0fjQtpuNX4ioKK$!u$*&zLF4kv^$bBe8`Xo4;uzJ0 z`&UjN;Yky504M^0VgM*wb?ry5hTRaq`=R$wI0c+QP$&2SAvuGlSLIdxVCRT|FA=j4 zH@S9@!j`&^?_?4{&LQBzAv44y&;dit!eGCiusZre{d%_t@@a>N_n-NC8dIeZg3O*p&}^ECML$Qz)WMWw$R!^{QhqlU@OI9SmSC7Fs%F=#Rj!j9$%k*%K$s4 z1PBCAykQND`J?QE*&)5^r1>oa?6~4T5IhNV>4adOB>GvwJ?^CWpT6Nvc)f+HX~n<^ zK(MQMuR3XdD*<*~@t-ev!UHFwolq!P@~siLlM!DGiHe_dLW^Nj28GMK;J=*-{vYpo V6}ArjINJaK002ovPDHLkV1gv5Rigj^ literal 0 HcmV?d00001 diff --git a/src/hi16-app-qalculate_kde.png b/src/hi16-app-qalculate_kde.png new file mode 100644 index 0000000000000000000000000000000000000000..0a464603e06575e975f042bf45980dcd501a1309 GIT binary patch literal 664 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 N002ovPDHLkV1oAp^4S0Y literal 0 HcmV?d00001 diff --git a/src/hi48-app-qalculate_kde.png b/src/hi48-app-qalculate_kde.png new file mode 100644 index 0000000000000000000000000000000000000000..fdde4fce25332587fe880cde169f55d8534b5e56 GIT binary patch literal 3874 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 literal 0 HcmV?d00001 diff --git a/src/kqalculate.cpp b/src/kqalculate.cpp new file mode 100644 index 0000000..ce0ac09 --- /dev/null +++ b/src/kqalculate.cpp @@ -0,0 +1,6676 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include + +#include "kqalculate.h" +#include "qalculateinsertfunctiondialog.h" +#include "qalculate_kde_utils.h" +#include "preferences.h" +#include "qalculatepreferencesdialog.h" +#include "qalculateimportcsvdialog.h" +#include "qalculateexportcsvdialog.h" +#include "qalculateexpressionedit.h" +#include "qalculateprecisiondialog.h" +#include "qalculatedecimalsdialog.h" +#include "qalculateeditvariabledialog.h" +#include "qalculateeditmatrixvectordialog.h" +#include "qalculateeditunitdialog.h" +#include "qalculateeditfunctiondialog.h" +#include "qalculateeditdatasetdialog.h" +#include "qalculateeditunknownvariabledialog.h" +#include "qalculatevariablesdialog.h" +#include "qalculatefunctionsdialog.h" +#include "qalculateunitsdialog.h" +#include "qalculatedatasetsdialog.h" +#include "qalculateconvertunitsdialog.h" +#include "qalculateconvertnumberbasesdialog.h" +#include "qalculateperiodictabledialog.h" +#include "qalculateplotdialog.h" +#include "qalculatesetbasedialog.h" +#include "qalculateinsertmatrixvectordialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qalculateresultdisplay.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR > 1 +#include +#endif +#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4 +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 2 +#include +#endif +#include +#include +#include +#include +#include +#include + +MathStructure *mstruct, *matrix_mstruct, *parsed_mstruct, *parsed_tostruct; +QString result_text, result_history_text, parsed_text; +QWidget *expressionWidget, *resultWidget, *statusWidget_l; +QWidget *topWidget; +KQalculate *mainWin = 0; +bool prev_result_approx; +extern bool close_to_systray; +extern bool display_expression_status; +extern QColor status_error_color; +extern QColor status_warning_color; +extern int use_icon_buttons; +extern bool enable_expression_completion; + +extern QString initial_history; +extern tree_struct function_cats, unit_cats, variable_cats; +extern vector ia_units, ia_variables, ia_functions; +extern vector recent_functions; +extern vector recent_variables; +extern vector recent_units; +vector result_parts; + +KnownVariable *vans[5]; +int vans_id_start[5]; +int vans_id_end[5]; + +extern PrintOptions printops; +extern EvaluationOptions evalops; +extern bool rpn_mode, rpn_keypad_only; +extern bool save_mode_on_exit, save_defs_on_exit; + +extern bool canplot; + +extern bool use_custom_result_font, use_custom_expression_font, use_custom_status_font; +extern QString custom_result_font, custom_expression_font, custom_status_font; + +extern QTimer *error_timer; + +extern QStringList expression_history; + +bool expression_has_changed, expression_has_changed2, had_errors_before, had_warnings_before, block_result_update; + +FILE *view_pipe_r, *view_pipe_w, *command_pipe_r, *command_pipe_w; +pthread_t view_thread, command_thread; +pthread_attr_t view_thread_attr, command_thread_attr; +bool b_busy, command_thread_started; +int saved_divisionline_height = 0; +uint initial_result_index = 0; + +extern bool show_keypad, show_history, show_stack; + +extern vector modes; + +extern QValueVector inhistory; +extern QValueVector inhistory_type; +extern QValueVector inhistory_id; +extern int inhistory_current_id; +int initial_inhistory_index = 0; + +const MathStructure *KQalculate::getResultPart(int i) { + if(i < 1 || (size_t) i > result_parts.size()) return NULL; + return &result_parts[(size_t) i - 1]; +} + +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 +#include +#include +QPixmap loadSystrayIcon(const QString &icon) { + KConfig *appCfg = kapp->config(); + KConfigGroupSaver configSaver(appCfg, "System Tray"); + int iconWidth = appCfg->readNumEntry("systrayIconWidth", 22); + return KGlobal::instance()->iconLoader()->loadIcon(icon, KIcon::Panel, iconWidth); +} +#endif + +#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 3 +#define ICON_SIZE_SMALL_MEDIUM KIcon::SizeSmallMedium +#else +#define ICON_SIZE_SMALL_MEDIUM 22 +#endif + +ModeObject::ModeObject(int mode) : i_mode(mode) {} +void ModeObject::loadMode() { + mainWin->loadMode(i_mode); +} + +KQalculate::KQalculate(KUniqueApplication *parent, const char* name, WFlags fl) : KMainWindow(0, name, fl) { + + if(!name) setName("kqalculate"); + + m_parent = parent; + + vans_id_start[0] = -1; + vans_id_end[0] = -1; + vans_id_start[1] = -1; + vans_id_end[1] = -1; + vans_id_start[2] = -1; + vans_id_end[2] = -1; + vans_id_start[3] = -1; + vans_id_end[3] = -1; + vans_id_start[4] = -1; + vans_id_end[4] = -1; + + QStyleSheet::setDefaultSheet(new QalculateStyleSheet()); + + insert_matrix_dialog = NULL; + preferences_dialog = NULL; + precisionDialog = NULL; + decimalsDialog = NULL; + variable_edit_dialog = NULL; + store_dialog = NULL; + matrix_edit_dialog = NULL; + import_csv_dialog = NULL; + export_csv_dialog = NULL; + unit_edit_dialog = NULL; + function_edit_dialog = NULL; + dataset_edit_dialog = NULL; + unknown_edit_dialog = NULL; + variables_dialog = NULL; + functions_dialog = NULL; + units_dialog = NULL; + datasets_dialog = NULL; + convert_to_unit_expression_dialog = NULL; + convert_number_bases_dialog = NULL; + periodic_table_dialog = NULL; + plot_dialog = NULL; + set_base_dialog = NULL; + + prev_result_approx = false; + expression_has_changed = false; + expression_has_changed2 = false; + had_errors_before = false; + had_warnings_before = false; + block_result_update = false; + + history_height = 0; + + trayicon = NULL; + ActionHideSystemTrayIcon = new KAction(i18n("Remove from System Tray"), "hidesystemtrayicon", 0, this, SLOT(hideSystemTrayIcon()), actionCollection(), "hide_system_tray_icon"); + ActionHide = new KAction(i18n("Hide"), "hide", 0, this, SLOT(hide()), actionCollection(), "hide"); + showSystemTrayIcon(close_to_systray); + + setCentralWidget(new QWidget(this)); + QVBoxLayout *mainLayout = new QVBoxLayout(centralWidget(), 11, 6); + mainLayout->setResizeMode(QLayout::Minimum); + + QHBoxLayout *topLayout = new QHBoxLayout(0, 0, 6); + + bool use_button_pixmaps = false; + if(use_icon_buttons > 0) { + use_button_pixmaps = true; + } else if(use_icon_buttons < 0) { + KConfig config("kdeglobals", true, false); + config.setGroup("KDE"); + use_button_pixmaps = config.readBoolEntry("ShowIconsOnPushButtons", false); + } + + if(use_button_pixmaps) leftButtonsLayout = new QVBoxLayout(0, 0, 3); + else leftButtonsLayout = new QVBoxLayout(0, 0, 6); + if(use_button_pixmaps) executeButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("exec", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", centralWidget()); + else if(rpn_mode) executeButton = new QalculateButton(i18n("Enter"), centralWidget()); + else executeButton = new QalculateButton(i18n("="), centralWidget()); + executeButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false); + if(rpn_mode) QToolTip::add(executeButton, i18n("Calculate expression and add to stack")); + else QToolTip::add(executeButton, i18n("Calculate expression")); + leftButtonsLayout->addWidget(executeButton); + leftButtonsSeparator = new KSeparator(Qt::Horizontal, centralWidget()); + leftButtonsLayout->addWidget(leftButtonsSeparator); + if(use_button_pixmaps) leftButtonsSeparator->hide(); + if(use_button_pixmaps) storeButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("filesaveas", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", centralWidget()); + else storeButton = new QalculateButton(i18n("Store"), centralWidget()); + storeButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false); + QToolTip::add(storeButton, i18n("Store result as variable")); + leftButtonsLayout->addWidget(storeButton); + if(use_button_pixmaps) convertButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("qalculate_convert", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", centralWidget()); + else convertButton = new QalculateButton(i18n("Convert"), centralWidget()); + convertButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false); + QToolTip::add(convertButton, i18n("Convert units in result")); + leftButtonsLayout->addWidget(convertButton); + leftButtonsLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Minimum)); + + QVBoxLayout *expressionLayout = new QVBoxLayout(0, 0, 0); + expressionEdit = new QalculateExpressionEdit(true, centralWidget()); + expressionLayout->addWidget(expressionEdit); + expressionEdit->setFocus(); + expressionEdit->expression_history = expression_history; + if(!enable_expression_completion) expressionEdit->disableCompletion(); + QToolTip::add(expressionEdit, i18n("Enter expression here")); + QHBoxLayout *statusLayout = new QHBoxLayout(0, 0, 6); + statusLabel_l = new QalculateParseLabel(centralWidget()); + statusLabel_l->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false); + statusLabel_l->setLineWidth(0); + statusLabel_l->setMargin(0); + statusLabel_l->setAlignment(int(QLabel::AlignTop | QLabel::AlignLeft)); + if(!display_expression_status) statusLabel_l->hide(); + statusLayout->addWidget(statusLabel_l); + statusLabel_r = new QLabel(i18n("status"), centralWidget()); + statusLabel_r->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum, false); + statusLabel_r->setLineWidth(0); + statusLabel_r->setMargin(0); + statusLabel_r->setTextFormat(Qt::RichText); + statusLabel_r->setAlignment(int(QLabel::AlignTop | QLabel::AlignRight)); + statusLayout->addWidget(statusLabel_r); + expressionLayout->addLayout(statusLayout); + resultLabel = new QalculateResultDisplay(centralWidget()); + resultLabel->setRightMargin(10); + expressionLayout->addWidget(resultLabel); + + topLayout->addLayout(expressionLayout); + topLayout->addLayout(leftButtonsLayout); + mainLayout->addLayout(topLayout); + + resultLabel->setWordWrap(QTextEdit::WidgetWidth); + resultLabel->setMargin(0); + + bottomLine = new KSeparator(Qt::Horizontal, centralWidget()); + mainLayout->addWidget(bottomLine); + + mainStack = new QWidgetStack(centralWidget()); + mainStack->setEnabled(true); + mainStack->setSizePolicy(QSizePolicy((QSizePolicy::SizeType) 5, (QSizePolicy::SizeType) 7, 0, 0, mainStack->sizePolicy().hasHeightForWidth())); + + keypadPage = new QWidget(mainStack); + QVBoxLayout *keypadPageLayout = new QVBoxLayout(keypadPage, 0, 12); + + keypadPageLayout->addWidget(new KSeparator(Qt::Horizontal, keypadPage)); + + QHBoxLayout *keypadTopLayout = new QHBoxLayout(0, 0, 6); + kpExact = new QalculateButton(i18n("Exact"), keypadPage); + QToolTip::add(kpExact, i18n("Toggle exact mode")); + kpExact->setToggleButton(true); + keypadTopLayout->addWidget(kpExact); + kpFraction = new QalculateButton(i18n("Fraction"), keypadPage); + QToolTip::add(kpFraction, i18n("Toggle fractional display")); + kpFraction->setToggleButton(true); + keypadTopLayout->addWidget(kpFraction); + kpNumericCombo = new QComboBox(true, keypadPage); + QToolTip::add(kpNumericCombo, i18n("Numerical display")); + kpNumericCombo->setEditable(false); + keypadTopLayout->addWidget(kpNumericCombo); + kpNumericCombo->insertItem(i18n("Normal")); + kpNumericCombo->insertItem(i18n("Engineering")); + kpNumericCombo->insertItem(i18n("Scientific")); + kpNumericCombo->insertItem(i18n("Pure")); + kpNumericCombo->insertItem(i18n("Simple")); + kpBaseCombo = new QComboBox(true, keypadPage); + QToolTip::add(kpBaseCombo, i18n("Base in result")); + kpBaseCombo->setEditable(false); + keypadTopLayout->addWidget(kpBaseCombo); + keypadPageLayout->addLayout(keypadTopLayout); + kpBaseCombo->insertItem(i18n("Binary")); + kpBaseCombo->insertItem(i18n("Octal")); + kpBaseCombo->insertItem(i18n("Decimal")); + kpBaseCombo->insertItem(i18n("Hexadecimal")); + kpBaseCombo->insertItem(i18n("Sexagesimal")); + kpBaseCombo->insertItem(i18n("Time Format")); + kpBaseCombo->insertItem(i18n("Roman")); + kpBaseCombo->insertItem(i18n("Other...")); + + QHBoxLayout *keypadBottomLayout = new QHBoxLayout(0, 0, 24); + + QGridLayout *keypadFunctionsLayout = new QGridLayout(0, 5, 3, 0, 6); + + functionsButton = new QalculateButton(i18n("f(x)"), keypadPage); + QFont fb_font(functionsButton->font()); + fb_font.setItalic(true); + functionsButton->setFont(fb_font); + QToolTip::add(functionsButton, i18n("Open functions manager")); + keypadFunctionsLayout->addWidget(functionsButton, 0, 0); + kpSqrt = new QalculateButton(i18n("sqrt"), keypadPage); + QToolTip::add(kpSqrt, i18n("Square root")); + keypadFunctionsLayout->addWidget(kpSqrt, 1, 0); + kpRaise = new QalculateButton(keypadPage); + kpRaise->setMarkup(i18n("xy")); + QToolTip::add(kpRaise, i18n("Raise (Ctrl+*)")); + keypadFunctionsLayout->addWidget(kpRaise, 0, 1); + kpSquare = new QalculateButton(keypadPage); + kpSquare->setMarkup(i18n("x2")); + QToolTip::add(kpSquare, i18n("Square")); + keypadFunctionsLayout->addWidget(kpSquare, 0, 2); + kpLog = new QalculateButton(i18n("log"), keypadPage); + QToolTip::add(kpLog, i18n("Base-10 logarithm")); + keypadFunctionsLayout->addWidget(kpLog, 1, 1); + kpLn = new QalculateButton(i18n("ln"), keypadPage); + QToolTip::add(kpLn, i18n("Natural logarithm")); + keypadFunctionsLayout->addWidget(kpLn, 1, 2); + kpFactorial = new QalculateButton(i18n("x!"), keypadPage); + QToolTip::add(kpFactorial, i18n("Factorial")); + keypadFunctionsLayout->addWidget(kpFactorial, 2, 0); + kpCos = new QalculateButton(i18n("cos"), keypadPage); + QToolTip::add(kpCos, i18n("Cosine")); + keypadFunctionsLayout->addWidget(kpCos, 2, 1); + kpTan = new QalculateButton(i18n("tan"), keypadPage); + QToolTip::add(kpTan, i18n("Tangent")); + keypadFunctionsLayout->addWidget(kpTan, 2, 2); + kpHyp = new QalculateButton(i18n("hyp"), keypadPage); + QToolTip::add(kpHyp, i18n("Toggle hyperbolic functions")); + kpHyp->setToggleButton(true); + keypadFunctionsLayout->addWidget(kpHyp, 3, 0); + kpInv = new QalculateButton(i18n("inv"), keypadPage); + QToolTip::add(kpInv, i18n("Toggle inverse functions")); + kpInv->setToggleButton(true); + keypadFunctionsLayout->addWidget(kpInv, 3, 1); + kpSin = new QalculateButton(i18n("sin"), keypadPage); + QToolTip::add(kpSin, i18n("Sine")); + keypadFunctionsLayout->addWidget(kpSin, 3, 2); + QHBoxLayout *keypadAngleLayout = new QHBoxLayout(0, 0, 6); + kpAngleGroup = new QButtonGroup(); + kpAngleGroup->setExclusive(true); + kpDegreesButton = new QRadioButton(i18n("Deg"), keypadPage); + QToolTip::add(kpDegreesButton, i18n("Angle Unit: Degrees")); + kpAngleGroup->insert(kpDegreesButton, 0); + keypadAngleLayout->addWidget(kpDegreesButton); + kpRadiansButton = new QRadioButton(i18n("Rad"), keypadPage); + QToolTip::add(kpRadiansButton, i18n("Angle Unit: Radians")); + kpAngleGroup->insert(kpRadiansButton, 1); + keypadAngleLayout->addWidget(kpRadiansButton); + kpGradiansButton = new QRadioButton(i18n("Gra"), keypadPage); + QToolTip::add(kpGradiansButton, i18n("Angle Unit: Gradians")); + kpAngleGroup->insert(kpGradiansButton, 2); + keypadAngleLayout->addWidget(kpGradiansButton); + kpNoAngleUnitButton = new QRadioButton(i18n("None"), keypadPage); + kpAngleGroup->insert(kpNoAngleUnitButton, 3); + keypadAngleLayout->addWidget(kpNoAngleUnitButton); + kpNoAngleUnitButton->hide(); + keypadAngleLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum)); + keypadFunctionsLayout->addMultiCellLayout(keypadAngleLayout, 4, 4, 0, 2); + +#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4 + KAcceleratorManager::setNoAccel(kpDegreesButton); + KAcceleratorManager::setNoAccel(kpRadiansButton); + KAcceleratorManager::setNoAccel(kpGradiansButton); + KAcceleratorManager::setNoAccel(kpNoAngleUnitButton); +#endif + + keypadBottomLayout->addLayout(keypadFunctionsLayout); + + QGridLayout *keypadBasicsLayout = new QGridLayout(0, 1, 1, 0, 6); + kp7 = new QalculateButton(i18n("7"), keypadPage); + keypadBasicsLayout->addWidget(kp7, 0, 0); + kp8 = new QalculateButton(i18n("8"), keypadPage); + keypadBasicsLayout->addWidget(kp8, 0, 1); + kp9 = new QalculateButton(i18n("9"), keypadPage); + keypadBasicsLayout->addWidget(kp9, 0, 2); + kp4 = new QalculateButton(i18n("4"), keypadPage); + keypadBasicsLayout->addWidget(kp4, 1, 0); + kp5 = new QalculateButton(i18n("5"), keypadPage); + keypadBasicsLayout->addWidget(kp5, 1, 1); + kp6 = new QalculateButton(i18n("6"), keypadPage); + keypadBasicsLayout->addWidget(kp6, 1, 2); + kp1 = new QalculateButton(i18n("1"), keypadPage); + keypadBasicsLayout->addWidget(kp1, 2, 0); + kp2 = new QalculateButton(i18n("2"), keypadPage); + keypadBasicsLayout->addWidget(kp2, 2, 1); + kp3 = new QalculateButton(i18n("3"), keypadPage); + keypadBasicsLayout->addWidget(kp3, 2, 2); + kp0 = new QalculateButton(i18n("0"), keypadPage); + keypadBasicsLayout->addWidget(kp0, 3, 0); + kpDot = new QalculateButton(".", keypadPage); + QToolTip::add(kpDot, i18n("Decimal point")); + keypadBasicsLayout->addWidget(kpDot, 3, 1); + kpExp = new QalculateButton(i18n("EXP"), keypadPage); + QToolTip::add(kpExp, i18n("10^x (Ctrl+Shift+E)")); + keypadBasicsLayout->addWidget(kpExp, 3, 2); + + kpDel = new QalculateButton(i18n("Del"), keypadPage); + QToolTip::add(kpDel, i18n("Delete")); + keypadBasicsLayout->addWidget(kpDel, 0, 3); + kpClear = new QalculateButton(i18n("AC"), keypadPage); + QToolTip::add(kpClear, i18n("Clear")); + keypadBasicsLayout->addWidget(kpClear, 0, 4); + kpTimes = new QalculateButton("*", keypadPage); + QToolTip::add(kpTimes, i18n("Multiply")); + keypadBasicsLayout->addWidget(kpTimes, 1, 3); + kpDivision = new QalculateButton("/", keypadPage); + QToolTip::add(kpDivision, i18n("Divide")); + keypadBasicsLayout->addWidget(kpDivision, 1, 4); + kpPlus = new QalculateButton("+", keypadPage); + QToolTip::add(kpPlus, i18n("Add")); + keypadBasicsLayout->addWidget(kpPlus, 2, 3); + kpMinus = new QalculateButton("-", keypadPage); + QToolTip::add(kpMinus, i18n("Subtract")); + keypadBasicsLayout->addWidget(kpMinus, 2, 4); + kpAns = new QalculateButton(i18n("Ans"), keypadPage); + QToolTip::add(kpAns, i18n("Previous result")); + keypadBasicsLayout->addWidget(kpAns, 3, 3); + if(rpn_mode) kpEquals = new QalculateButton(i18n("Ent"), keypadPage); + else kpEquals = new QalculateButton(i18n("="), keypadPage); + if(rpn_mode) QToolTip::add(kpEquals, i18n("Calculate expression and add to stack")); + else QToolTip::add(kpEquals, i18n("Calculate expression")); + keypadBasicsLayout->addWidget(kpEquals, 3, 4); + keypadBottomLayout->addLayout(keypadBasicsLayout); + + keypadPageLayout->addLayout(keypadBottomLayout); + + keypadPageLayout->addWidget(new KSeparator(Qt::Horizontal, keypadPage)); + mainStack->addWidget(keypadPage, 0); + + historyPage = new QWidget(mainStack, "historyPage"); + QVBoxLayout *historyPageLayout = new QVBoxLayout(historyPage, 0, 0); + historyBrowser = new QalculateHistoryBrowser(historyPage, "historyBrowser"); + historyBrowser->setTextFormat(KTextBrowser::RichText); + historyBrowser->setWordWrap(KTextBrowser::NoWrap); + historyPageLayout->addWidget(historyBrowser); + mainStack->addWidget(historyPage, 1); + + stackPage = new QWidget(mainStack, "stackPage"); + QHBoxLayout *stackPageLayout = new QHBoxLayout(stackPage, 0, 6); + stackList = new QalculateRPNStackListView(stackPage, "stackList"); + stackList->addColumn(i18n("Index")); + stackList->addColumn(i18n("Value")); + stackList->setColumnAlignment(0, Qt::AlignCenter); + stackList->setColumnAlignment(1, Qt::AlignRight); + stackList->setFullWidth(true); + stackList->setResizeMode(QListView::LastColumn); + stackList->setSelectionMode(QListView::Single); + stackList->setAllColumnsShowFocus(true); + stackList->setRootIsDecorated(false); + stackList->setItemsMovable(true); + stackList->setDragEnabled(true); + stackList->setAcceptDrops(true); + stackList->setSorting(-1); + stackList->setItemsRenameable(true); + stackList->setRenameable(1, true); + stackList->setRenameable(0, false); + stackPageLayout->addWidget(stackList); + if(use_button_pixmaps) stackPageButtonsLayout = new QVBoxLayout(stackPageLayout, 3); + else stackPageButtonsLayout = new QVBoxLayout(stackPageLayout, 6); + if(use_button_pixmaps) registerUpButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("up", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage); + else registerUpButton = new QalculateButton(i18n("Up"), stackPage); + QToolTip::add(registerUpButton, i18n("Move selected register up")); + registerUpButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false); + stackPageButtonsLayout->addWidget(registerUpButton); + if(use_button_pixmaps) registerDownButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("down", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage); + else registerDownButton = new QalculateButton(i18n("Down"), stackPage); + QToolTip::add(registerDownButton, i18n("Move selected register down")); + registerDownButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false); + stackPageButtonsLayout->addWidget(registerDownButton); + if(use_button_pixmaps) editRegisterButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("edit", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage); + else editRegisterButton = new QalculateButton(i18n("Edit"), stackPage); + QToolTip::add(editRegisterButton, i18n("Edit value of selected register")); + editRegisterButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false); + stackPageButtonsLayout->addWidget(editRegisterButton); + if(use_button_pixmaps) deleteRegisterButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("editdelete", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage); + else deleteRegisterButton = new QalculateButton(i18n("Delete"), stackPage); + QToolTip::add(deleteRegisterButton, i18n("Delete selected register")); + deleteRegisterButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false); + stackPageButtonsLayout->addWidget(deleteRegisterButton); + if(use_button_pixmaps) clearStackButton = new QalculateButton(KApplication::kApplication()->iconLoader()->loadIconSet("view_remove", KIcon::Small, ICON_SIZE_SMALL_MEDIUM), "", stackPage); + else clearStackButton = new QalculateButton(i18n("Clear"), stackPage); + QToolTip::add(clearStackButton, i18n("Clear the RPN stack")); + clearStackButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed, false); + registerUpButton->setEnabled(false); + registerDownButton->setEnabled(false); + editRegisterButton->setEnabled(false); + deleteRegisterButton->setEnabled(false); + clearStackButton->setEnabled(false); + stackPageButtonsLayout->addWidget(clearStackButton); + stackPageButtonsLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding)); + mainStack->addWidget(stackPage, 2); + + updateButtonWidths(); + + mainLayout->addWidget(mainStack); + + QHBoxLayout *bottomLayout = new QHBoxLayout(0, 0, 6); + keypadButton = new QPushButton(i18n("Keypad"), centralWidget()); + QToolTip::add(keypadButton, i18n("Show/hide keypad")); + keypadButton->setToggleButton(true); + bottomLayout->addWidget(keypadButton); + historyButton = new QPushButton(i18n("History"), centralWidget()); + QToolTip::add(historyButton, i18n("Show/hide history")); + historyButton->setToggleButton(true); + bottomLayout->addWidget(historyButton); + stackButton = new QPushButton(i18n("RPN Stack"), centralWidget()); + QToolTip::add(stackButton, i18n("Show/hide RPN stack")); + stackButton->setToggleButton(true); + bottomLayout->addWidget(stackButton); + if(!rpn_mode) stackButton->hide(); + bottomLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum)); + mainLayout->addLayout(bottomLayout); + + connect(stackList, SIGNAL(selectionChanged()), this, SLOT(registerSelected())); + connect(stackList, SIGNAL(itemRenamed(QListViewItem*)), this, SLOT(stackRegisterSet(QListViewItem*))); + connect(stackList, SIGNAL(moved()), this, SLOT(stackRegisterMoved())); + connect(stackList, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)), this, SLOT(popupStackMenu(KListView*, QListViewItem*, const QPoint&))); + connect(registerUpButton, SIGNAL(clicked()), this, SLOT(registerUp())); + connect(registerDownButton, SIGNAL(clicked()), this, SLOT(registerDown())); + connect(editRegisterButton, SIGNAL(clicked()), this, SLOT(editRegister())); + connect(deleteRegisterButton, SIGNAL(clicked()), this, SLOT(deleteRegister())); + connect(clearStackButton, SIGNAL(clicked()), this, SLOT(clearStack())); + connect(stackButton, SIGNAL(toggled(bool)), this, SLOT(toggleStack(bool))); + connect(historyButton, SIGNAL(toggled(bool)), this, SLOT(toggleHistory(bool))); + connect(keypadButton, SIGNAL(toggled(bool)), this, SLOT(toggleKeypad(bool))); + connect(kp0, SIGNAL(clicked()), this, SLOT(insertKP0())); + connect(kp1, SIGNAL(clicked()), this, SLOT(insertKP1())); + connect(kp2, SIGNAL(clicked()), this, SLOT(insertKP2())); + connect(kp3, SIGNAL(clicked()), this, SLOT(insertKP3())); + connect(kp4, SIGNAL(clicked()), this, SLOT(insertKP4())); + connect(kp5, SIGNAL(clicked()), this, SLOT(insertKP5())); + connect(kp6, SIGNAL(clicked()), this, SLOT(insertKP6())); + connect(kp7, SIGNAL(clicked()), this, SLOT(insertKP7())); + connect(kp8, SIGNAL(clicked()), this, SLOT(insertKP8())); + connect(kp9, SIGNAL(clicked()), this, SLOT(insertKP9())); + connect(kpDot, SIGNAL(clicked()), this, SLOT(insertDot())); + connect(kpExp, SIGNAL(clicked()), this, SLOT(insertExp())); + connect(kpAns, SIGNAL(clicked()), this, SLOT(insertAns())); + connect(kpEquals, SIGNAL(clicked()), this, SLOT(execute())); + connect(kpPlus, SIGNAL(clicked()), this, SLOT(insertPlus())); + connect(kpMinus, SIGNAL(clicked()), this, SLOT(insertMinus())); + connect(kpTimes, SIGNAL(clicked()), this, SLOT(insertTimes())); + connect(kpDivision, SIGNAL(clicked()), this, SLOT(insertDivision())); + connect(kpDel, SIGNAL(clicked()), this, SLOT(expressionDel())); + connect(kpClear, SIGNAL(clicked()), this, SLOT(clearExpression())); + connect(kpSin, SIGNAL(clicked()), this, SLOT(insertSin())); + connect(kpCos, SIGNAL(clicked()), this, SLOT(insertCos())); + connect(kpTan, SIGNAL(clicked()), this, SLOT(insertTan())); + connect(kpSqrt, SIGNAL(clicked()), this, SLOT(insertSqrt())); + connect(kpLog, SIGNAL(clicked()), this, SLOT(insertLog())); + connect(kpLn, SIGNAL(clicked()), this, SLOT(insertLn())); + connect(kpRaise, SIGNAL(clicked()), this, SLOT(insertRaise())); + connect(kpSquare, SIGNAL(clicked()), this, SLOT(insertSquare())); + connect(kpFraction, SIGNAL(toggled(bool)), this, SLOT(setFractionMode(bool))); + connect(kpExact, SIGNAL(toggled(bool)), this, SLOT(setExactMode(bool))); + connect(kpAngleGroup, SIGNAL(clicked(int)), this, SLOT(kpSetAngleUnit(int))); + connect(kpBaseCombo->listBox(), SIGNAL(selected(int)), this, SLOT(kpSetBaseSelected(int))); + connect(kpBaseCombo, SIGNAL(activated(int)), this, SLOT(kpSetBase(int))); + connect(kpNumericCombo, SIGNAL(activated(int)), this, SLOT(kpSetNumericalMode(int))); + //connect(kpMod, SIGNAL(clicked()), this, SLOT(insertMod())); + connect(kpFactorial, SIGNAL(clicked()), this, SLOT(insertFactorial())); + //connect(expressionEdit, SIGNAL(returnPressed()), this, SLOT(execute())); + connect(expressionEdit, SIGNAL(textChanged(const QString&)), this, SLOT(onExpressionChanged())); + connect(storeButton, SIGNAL(clicked()), this, SLOT(storeResult())); + connect(executeButton, SIGNAL(clicked()), this, SLOT(execute())); + connect(convertButton, SIGNAL(clicked()), this, SLOT(convertToUnitExpression())); + connect(functionsButton, SIGNAL(clicked()), this, SLOT(manageFunctions())); + connect(expressionEdit, SIGNAL(cursorMoved()), this, SLOT(displayParseStatus())); + connect(expressionEdit->qalculateCompletionBox, SIGNAL(hidden()), statusLabel_l, SLOT(update())); + + //tab order + setTabOrder(expressionEdit, resultLabel); + setTabOrder(resultLabel, historyBrowser); + setTabOrder(historyBrowser, keypadButton); + setTabOrder(keypadButton, historyButton); + setTabOrder(historyButton, stackButton); + + if(show_stack && rpn_mode) { + bottomLine->hide(); + stackButton->setOn(true); + mainStack->raiseWidget(2); + mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false); + resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false); + } else if(show_keypad) { + bottomLine->hide(); + keypadButton->setOn(true); + mainStack->raiseWidget(0); + mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false); + resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false); + } else if(show_history) { + bottomLine->hide(); + historyButton->setOn(true); + mainStack->raiseWidget(1); + mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false); + resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false); + } else { + mainStack->hide(); + mainStack->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum, false); + resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false); + } + + initial_history = ""; + + for(QValueVector::size_type i = 0; i < inhistory.size(); i++) { + switch(inhistory_type[i]) { + case QALCULATE_HISTORY_EXPRESSION: { + if(i != 0) { + initial_history += "


"; + } + initial_history += ""; + initial_history += inhistory[i]; + initial_history += ""; + initial_history += " "; + break; + } + case QALCULATE_HISTORY_REGISTER_MOVED: { + if(i != 0) { + initial_history += "

"; + } + initial_history += i18n("RPN Register Moved"); + initial_history += "
"; + break; + } + case QALCULATE_HISTORY_TRANSFORMATION: { + initial_history += ""; + initial_history += ""; + initial_history += inhistory[i]; + initial_history += ""; + initial_history += ": "; + break; + } + case QALCULATE_HISTORY_RESULT: { + initial_history += ""; + initial_history += "= "; + initial_history += ""; + initial_history += ""; + initial_history += ""; + initial_history += inhistory[i]; + initial_history += ""; + initial_history += ""; + initial_history += "
"; + break; + } + case QALCULATE_HISTORY_RESULT_APPROXIMATE: { + initial_history += ""; + if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) historyBrowser)) { + initial_history += SIGN_ALMOST_EQUAL " "; + } else { + initial_history += "= "; + initial_history += i18n("approx."); + initial_history += " "; + } + initial_history += ""; + initial_history += ""; + initial_history += ""; + initial_history += inhistory[i]; + initial_history += ""; + initial_history += ""; + initial_history += "
"; + break; + } + case QALCULATE_HISTORY_PARSE: { + initial_history += "  = "; + initial_history += ""; + initial_history += ""; + initial_history += inhistory[i]; + initial_history += ""; + initial_history += ""; + initial_history += "
"; + break; + } + case QALCULATE_HISTORY_PARSE_APPROXIMATE: { + initial_history += "  "; + if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) historyBrowser)) { + initial_history += SIGN_ALMOST_EQUAL " "; + } else { + initial_history += "= "; + initial_history += i18n("approx."); + initial_history += " "; + } + initial_history += ""; + initial_history += ""; + initial_history += inhistory[i]; + initial_history += ""; + initial_history += ""; + initial_history += "
"; + break; + } + case QALCULATE_HISTORY_WARNING: { + initial_history += ""; + initial_history += "- "; + initial_history += inhistory[i]; + initial_history += ""; + initial_history += "
"; + break; + } + case QALCULATE_HISTORY_ERROR: { + initial_history += ""; + initial_history += "- "; + initial_history += inhistory[i]; + initial_history += ""; + initial_history += "
"; + break; + } + case QALCULATE_HISTORY_OLD: { + initial_history += inhistory[i]; + initial_history += "
"; + break; + } + } + } + + historyBrowser->setText(initial_history); + initial_history = ""; + + if(use_custom_result_font) { + QFont new_font(resultLabel->font()); + new_font.fromString(custom_result_font); + resultLabel->setFont(new_font); + } else { + resultLabel->unsetFont(); + } + if(use_custom_expression_font) { + QFont new_font(expressionEdit->font()); + new_font.fromString(custom_expression_font); + expressionEdit->setFont(new_font); + } else { + expressionEdit->unsetFont(); + } + updateStatusLabelFonts(); + + set_unicode_buttons(); + + setupActions(); + + stackMenu = new QPopupMenu(this); + ActionEditRegister->plug(stackMenu); + ActionDeleteRegister->plug(stackMenu); + stackMenu->insertSeparator(); + ActionClearStack->plug(stackMenu); + + update_status_text(); + + bottomLine->setMinimumWidth(1000); + + createGUI("qalculate_kdeui.rc"); + + menuBar()->sizeHint(); + int h = menuBar()->height(); + int w = 300; + while(menuBar()->heightForWidth(w) > h && w < 1000) { + w += 10; + } + if(w >= 1000) { + bottomLine->setMinimumWidth(0); + w = 0; + } else { + bottomLine->setMinimumWidth(w - 22); + } + + if(!isShown()) adjustSize(); + setAutoSaveSettings(); + + if(show_history || (rpn_mode && show_stack)) { + resize(QSize(10, height()).expandedTo(minimumSizeHint())); + } else if(show_keypad) { + resize(minimumSizeHint()); + } else { + resize(QSize(width(), 10).expandedTo(minimumSizeHint())); + } + + menu_functions = (QPopupMenu*) factory()->container("functions", this); + menu_variables = (QPopupMenu*) factory()->container("variables", this); + menu_units = (QPopupMenu*) factory()->container("units", this); + menu_to_unit = (QPopupMenu*) factory()->container("convert_to_unit", this); + menu_set_prefix = (QPopupMenu*) factory()->container("set_prefix", this); + menu_modes = (QPopupMenu*) factory()->container("modes", this); + + QObject::connect(menu_modes, SIGNAL(activated(int)), this, SLOT(onModesMenuItemActivated(int))); + for(size_t i = 0; i < modes.size(); i++) { + menu_modes->insertItem(modes[i].name, -1, i); + if(i > 1) { + ModeObject *mo = new ModeObject(i); + mo->i_mode = i; + mode_objects.push_back(mo); + accel()->insert(QString("Load mode: ") + modes[i].name, i18n("Load meta mode: %1").arg(modes[i].name), QString::null, modes[i].shortcut, mo, SLOT(loadMode())); + } + } + + QObject::connect(menu_functions, SIGNAL(activated(int)), this, SLOT(onFunctionMenuItemActivated(int))); + QObject::connect(menu_variables, SIGNAL(activated(int)), this, SLOT(onVariableMenuItemActivated(int))); + QObject::connect(menu_units, SIGNAL(activated(int)), this, SLOT(onUnitMenuItemActivated(int))); + QObject::connect(menu_to_unit, SIGNAL(activated(int)), this, SLOT(onConvertToUnitMenuItemActivated(int))); + QObject::connect(menu_set_prefix, SIGNAL(activated(int)), this, SLOT(onSetPrefixMenuItemActivated(int))); + +} + +KQalculate::~KQalculate() {} + +void KQalculate::updateStatusLabelFonts() { + if(use_custom_status_font) { + QFont new_font(statusLabel_l->font()); + new_font.fromString(custom_status_font); + statusLabel_l->setFont(new_font); + new_font.setPointSizeFloat(new_font.pointSizeFloat() / 1.2); + statusLabel_r->setFont(new_font); + } else { + statusLabel_l->unsetFont(); + statusLabel_r->unsetFont(); + QFont new_font = statusLabel_l->font(); + new_font.setPointSizeFloat(new_font.pointSizeFloat() / 1.2); + statusLabel_l->setFont(new_font); + new_font = statusLabel_r->font(); + new_font.setPointSizeFloat(new_font.pointSizeFloat() / 1.44); + statusLabel_r->setFont(new_font); + } +} + +void KQalculate::updateButtonWidths() { + int button_width = executeButton->sizeHint().width(); + if(storeButton->sizeHint().width() > button_width) button_width = storeButton->sizeHint().width(); + if(convertButton->sizeHint().width() > button_width) button_width = convertButton->sizeHint().width(); + if(registerUpButton->sizeHint().width() > button_width) button_width = registerUpButton->sizeHint().width(); + if(registerDownButton->sizeHint().width() > button_width) button_width = registerDownButton->sizeHint().width(); + if(editRegisterButton->sizeHint().width() > button_width) button_width = editRegisterButton->sizeHint().width(); + if(deleteRegisterButton->sizeHint().width() > button_width) button_width = deleteRegisterButton->sizeHint().width(); + if(clearStackButton->sizeHint().width() > button_width) button_width = clearStackButton->sizeHint().width(); + clearStackButton->setMinimumWidth(button_width); + executeButton->setMinimumWidth(button_width); +} + +void KQalculate::fontChange(const QFont &old_font) { + updateStatusLabelFonts(); + functionsButton->unsetFont(); + QFont fb_font(functionsButton->font()); + fb_font.setItalic(true); + functionsButton->setFont(fb_font); + kpSquare->setMarkup(i18n("x2")); + kpRaise->setMarkup(i18n("xy")); + result_display_updated(); + KMainWindow::fontChange(old_font); + updateButtonWidths(); +} + +void KQalculate::showSystemTrayIcon(bool do_show) { + if(do_show && !trayicon) { + trayicon = new KSystemTray(this); + QObject::connect(trayicon, SIGNAL(quitSelected()), qApp, SLOT(quit())); +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + trayicon->setPixmap(loadSystrayIcon(PACKAGE)); +#else + trayicon->setPixmap(trayicon->loadIcon(PACKAGE)); +#endif +#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 2 + KPopupMenu* traypop = trayicon->contextMenu(); + ActionHideSystemTrayIcon->plug(traypop, 1); +#endif + QToolTip::add(trayicon, i18n("Qalculate! - Scientific Calculator")); + } + if(do_show) { + trayicon->show(); + } else if(trayicon) { + trayicon->hide(); + } +} +void KQalculate::hideSystemTrayIcon() { + showSystemTrayIcon(false); + close_to_systray = false; + show(); +} + +#define SET_TOGGLE_ACTION(action, value) action->blockSignals(true); action->setChecked(value); action->blockSignals(false); +#define SET_TOGGLE_ACTION_ON(action) action->blockSignals(true); action->setChecked(true); action->blockSignals(false); + +void KQalculate::setupActions() { + + ActionNewVariable = new KAction(i18n("Variable"), "filenew", 0, this, SLOT(newVariable()), actionCollection(), "new_variable"); + ActionNewMatrix = new KAction(i18n("Matrix"), "filenew", 0, this, SLOT(newMatrix()), actionCollection(), "new_matrix"); + ActionNewVector = new KAction(i18n("Vector"), "filenew", 0, this, SLOT(newVector()), actionCollection(), "new_vector"); + ActionNewUnknownVariable = new KAction(i18n("Unknown Variable"), "filenew", 0, this, SLOT(newUnknownVariable()), actionCollection(), "new_unknown_variable"); + ActionNewFunction = new KAction(i18n("Function"), "filenew", 0, this, SLOT(newFunction()), actionCollection(), "new_function"); + ActionNewDataSet = new KAction(i18n("Data Set"), "filenew", 0, this, SLOT(newDataSet()), actionCollection(), "new_data_set"); + ActionNewUnit = new KAction(i18n("Unit"), "filenew", 0, this, SLOT(newUnit()), actionCollection(), "new_unit"); + ActionImportCSVFile = new KAction(i18n("Import CSV File..."), "fileimport", 0, this, SLOT(importCSVFile()), actionCollection(), "import_csv_file"); + ActionExportCSVFile = new KAction(i18n("Export CSV File..."), "filexport", 0, this, SLOT(exportCSVFile()), actionCollection(), "export_csv_file"); + ActionStoreResult = new KAction(i18n("Store Result..."), "filesave", CTRL+Key_S, this, SLOT(storeResult()), actionCollection(), "store_result"); + ActionSaveAsImage = new KAction(i18n("Save Result Image..."), "filesave", 0, this, SLOT(saveAsImage()), actionCollection(), "save_as_image"); + ActionSaveDefinitions = new KAction(i18n("Save Definitions"), "filesave", 0, this, SLOT(saveDefinitions()), actionCollection(), "save_definitions"); + ActionUpdateExchangeRates = new KAction(i18n("Update Exchange Rates"), "reload", 0, this, SLOT(updateExchangeRates()), actionCollection(), "update_exchange_rates"); + ActionPlotFunctionsData = new KAction(i18n("Plot Functions/Data"), 0, this, SLOT(plotFunctionsData()), actionCollection(), "plot_functions_data"); + ActionPlotFunctionsData->setEnabled(canplot); + ActionConvertNumberBases = new KAction(i18n("Convert Number Bases"), 0, this, SLOT(convertNumberBases()), actionCollection(), "convert_number_bases"); + ActionPeriodicTable = new KAction(i18n("Periodic Table"), 0, this, SLOT(periodicTable()), actionCollection(), "periodic_table"); + if(close_to_systray) { + ActionClose = KStdAction::close(this, SLOT(close()), actionCollection()); + } else { + ActionClose = NULL; + } + globalAccel = new KGlobalAccel(this); + globalAccel->insert("Show/hide Qalculate!", i18n("Show/hide main Qalculate! window"), QString::null, KShortcut(), KShortcut(), this, SLOT(showHide())); + globalAccel->readSettings(); + globalAccel->updateConnections(); + ActionConfigureGlobalShortcuts = new KAction(i18n("Configure &Global Shortcuts..."), "configure_shortcuts", 0, this, SLOT(configureGlobalShortcuts()), actionCollection(), "configure_global_shortcuts"); + ActionQuit = KStdAction::quit(qApp, SLOT(quit()), actionCollection()); + ActionManageVariables = new KAction(i18n("Manage Variables"), Key_F2, this, SLOT(manageVariables()), actionCollection(), "manage_variables"); + ActionManageFunctions = new KAction(i18n("Manage Functions"), Key_F3, this, SLOT(manageFunctions()), actionCollection(), "manage_functions"); + ActionManageUnits = new KAction(i18n("Manage Units"), Key_F4, this, SLOT(manageUnits()), actionCollection(), "manage_units"); + ActionManageDataSets = new KAction(i18n("Manage Data Sets"), 0, this, SLOT(manageDataSets()), actionCollection(), "manage_data_sets"); + ActionFactorize = new KAction(i18n("Factorize"), 0, this, SLOT(factorize()), actionCollection(), "factorize"); + ActionSimplify = new KAction(i18n("Simplify"), 0, this, SLOT(simplify()), actionCollection(), "simplify"); + ActionSetUnknowns = new KAction(i18n("Set Unknowns..."), 0, this, SLOT(setUnknowns()), actionCollection(), "set_unknowns"); + ActionConvertToUnitExpression = new KAction(i18n("Convert to Unit Expression..."), CTRL+Key_T, this, SLOT(convertToUnitExpression()), actionCollection(), "convert_to_unit_expression"); + ActionConvertToBaseUnits = new KAction(i18n("Convert to Base Units"), 0, this, SLOT(convertToBaseUnits()), actionCollection(), "convert_to_base_units"); + ActionConvertToBestUnit = new KAction(i18n("Convert to Best Unit"), 0, this, SLOT(convertToBestUnit()), actionCollection(), "convert_to_best_unit"); + ActionInsertMatrix = new KAction(i18n("Insert Matrix..."), 0, this, SLOT(insertMatrix()), actionCollection(), "insert_matrix"); + ActionInsertVector = new KAction(i18n("Insert Vector..."), 0, this, SLOT(insertVector()), actionCollection(), "insert_vector"); + ActionCopyResult = new KAction(i18n("Copy Result"), "editcopy", Key_F5, this, SLOT(copyResult()), actionCollection(), "copy_result"); + ActionClearHistory = new KAction(i18n("Clear History"), "editclear", 0, this, SLOT(clearHistory()), actionCollection(), "clear_history"); + ActionPreferences = new KAction(i18n("Configure Qalculate!"), "configure", 0, this, SLOT(preferences()), actionCollection(), "preferences"); + KStdAction::keyBindings(guiFactory(), SLOT(configureShortcuts()), actionCollection(), "keybindings"); + ActionNumberBaseBinary = new KRadioAction(i18n("Binary"), 0, this, SLOT(numberBaseBinary()), actionCollection(), "number_base_binary"); + ActionNumberBaseBinary->setExclusiveGroup("group_number_base"); + ActionNumberBaseOctal = new KRadioAction(i18n("Octal"), 0, this, SLOT(numberBaseOctal()), actionCollection(), "number_base_octal"); + ActionNumberBaseOctal->setExclusiveGroup("group_number_base"); + ActionNumberBaseDecimal = new KRadioAction(i18n("Decimal"), 0, this, SLOT(numberBaseDecimal()), actionCollection(), "number_base_decimal"); + ActionNumberBaseDecimal->setExclusiveGroup("group_number_base"); + ActionNumberBaseHexadecimal = new KRadioAction(i18n("Hexadecimal"), 0, this, SLOT(numberBaseHexadecimal()), actionCollection(), "number_base_hexadecimal"); + ActionNumberBaseHexadecimal->setExclusiveGroup("group_number_base"); + ActionNumberBaseOther = new KRadioAction(i18n("Other..."), 0, this, SLOT(numberBaseOther()), actionCollection(), "number_base_other"); + ActionNumberBaseOther->setExclusiveGroup("group_number_base"); + ActionNumberBaseSexagesimal = new KRadioAction(i18n("Sexagesimal"), 0, this, SLOT(numberBaseSexagesimal()), actionCollection(), "number_base_sexagesimal"); + ActionNumberBaseSexagesimal->setExclusiveGroup("group_number_base"); + ActionNumberBaseTimeFormat = new KRadioAction(i18n("Time Format"), 0, this, SLOT(numberBaseTimeFormat()), actionCollection(), "number_base_time_format"); + ActionNumberBaseTimeFormat->setExclusiveGroup("group_number_base"); + ActionNumberBaseRomanNumerals = new KRadioAction(i18n("Roman Numerals"), 0, this, SLOT(numberBaseRomanNumerals()), actionCollection(), "number_base_roman_numerals"); + ActionNumberBaseRomanNumerals->setExclusiveGroup("group_number_base"); + ActionSetBase = new KAction(i18n("Select Result and Expression Base..."), CTRL+Key_B, this, SLOT(setBase()), actionCollection(), "set_base"); + ActionNumericalDisplayNormal = new KRadioAction(i18n("Normal"), 0, this, SLOT(numericalDisplayNormal()), actionCollection(), "numerical_display_normal"); + ActionNumericalDisplayNormal->setExclusiveGroup("group_numberical_display"); + ActionNumericalDisplayEngineering = new KRadioAction(i18n("Engineering"), 0, this, SLOT(numericalDisplayEngineering()), actionCollection(), "numerical_display_engineering"); + ActionNumericalDisplayEngineering->setExclusiveGroup("group_numberical_display"); + ActionNumericalDisplayScientific = new KRadioAction(i18n("Scientific"), 0, this, SLOT(numericalDisplayScientific()), actionCollection(), "numerical_display_scientific"); + ActionNumericalDisplayScientific->setExclusiveGroup("group_numberical_display"); + ActionNumericalDisplayPurelyScientific = new KRadioAction(i18n("Purely Scientific"), 0, this, SLOT(numericalDisplayPurelyScientific()), actionCollection(), "numerical_display_purely_scientific"); + ActionNumericalDisplayPurelyScientific->setExclusiveGroup("group_numberical_display"); + ActionNumericalDisplaySimple = new KRadioAction(i18n("Simple"), 0, this, SLOT(numericalDisplaySimple()), actionCollection(), "numerical_display_simple"); + ActionNumericalDisplaySimple->setExclusiveGroup("group_numberical_display"); + ActionIndicateInfiniteSeries = new KToggleAction(i18n("Indicate Infinite Series"), 0, actionCollection(), "indicate_infinite_series"); + QObject::connect(ActionIndicateInfiniteSeries, SIGNAL(toggled(bool)), this, SLOT(indicateInfiniteSeries(bool))); + ActionSortMinusLast = new KToggleAction(i18n("Sort Minus Last"), 0, actionCollection(), "sort_minus_last"); + QObject::connect(ActionSortMinusLast, SIGNAL(toggled(bool)), this, SLOT(sortMinusLast(bool))); + ActionNegativeExponents = new KToggleAction(i18n("Negative Exponents"), 0, actionCollection(), "negative_exponents"); + QObject::connect(ActionNegativeExponents, SIGNAL(toggled(bool)), this, SLOT(negativeExponents(bool))); + ActionShowEndingZeroes = new KToggleAction(i18n("Show Ending Zeroes"), 0, actionCollection(), "show_ending_zeroes"); + QObject::connect(ActionShowEndingZeroes, SIGNAL(toggled(bool)), this, SLOT(showEndingZeroes(bool))); + ActionRoundHalfwayNumbersToEven = new KToggleAction(i18n("Round Halfway Numbers to Even"), 0, actionCollection(), "round_halfway_numbers_to_even"); + QObject::connect(ActionRoundHalfwayNumbersToEven, SIGNAL(toggled(bool)), this, SLOT(roundHalfwayNumbersToEven(bool))); + ActionFractionalDisplayDecimal = new KRadioAction(i18n("Decimal"), 0, this, SLOT(fractionalDisplayDecimal()), actionCollection(), "fractional_display_decimal"); + ActionFractionalDisplayDecimal->setExclusiveGroup("group_fractional_display"); + ActionFractionalDisplayDecimalTryExact = new KRadioAction(i18n("Decimal (Try Exact)"), 0, this, SLOT(fractionalDisplayDecimalTryExact()), actionCollection(), "fractional_display_decimal_try_exact"); + ActionFractionalDisplayDecimalTryExact->setExclusiveGroup("group_fractional_display"); + ActionFractionalDisplayFraction = new KRadioAction(i18n("Fraction"), 0, this, SLOT(fractionalDisplayFraction()), actionCollection(), "fractional_display_fraction"); + ActionFractionalDisplayFraction->setExclusiveGroup("group_fractional_display"); + ActionFractionalDisplayCombined = new KRadioAction(i18n("Combined"), 0, this, SLOT(fractionalDisplayCombined()), actionCollection(), "fractional_display_combined"); + ActionFractionalDisplayCombined->setExclusiveGroup("group_fractional_display"); + ActionEnablePrefixes = new KToggleAction(i18n("Enable Prefixes"), 0, actionCollection(), "enable_prefixes"); + QObject::connect(ActionEnablePrefixes, SIGNAL(toggled(bool)), this, SLOT(enablePrefixes(bool))); + ActionEnableUseOfAllPrefixes = new KToggleAction(i18n("Enable Use of All SI Prefixes"), 0, actionCollection(), "enable_use_of_all_prefixes"); + QObject::connect(ActionEnableUseOfAllPrefixes, SIGNAL(toggled(bool)), this, SLOT(enableUseOfAllPrefixes(bool))); + ActionEnableDenominatorPrefixes = new KToggleAction(i18n("Enable Denominator Prefixes"), 0, actionCollection(), "enable_denominator_prefixes"); + QObject::connect(ActionEnableDenominatorPrefixes, SIGNAL(toggled(bool)), this, SLOT(enableDenominatorPrefixes(bool))); + ActionPlaceUnitsSeparately = new KToggleAction(i18n("Place Units Separately"), 0, actionCollection(), "place_units_separately"); + QObject::connect(ActionPlaceUnitsSeparately, SIGNAL(toggled(bool)), this, SLOT(placeUnitsSeparately(bool))); + ActionAutoNoConversion = new KRadioAction(i18n("No Automatic Conversion"), 0, this, SLOT(autoNoConversion()), actionCollection(), "auto_no_conversion"); + ActionAutoNoConversion->setExclusiveGroup("group_auto_conversion"); + ActionAutoConvertToBaseUnits = new KRadioAction(i18n("Convert to Base Units"), 0, this, SLOT(autoConvertToBaseUnits()), actionCollection(), "auto_convert_to_base_units"); + ActionAutoConvertToBaseUnits->setExclusiveGroup("group_auto_conversion"); + ActionAutoConvertToBestUnit = new KRadioAction(i18n("Convert to Best Unit"), 0, this, SLOT(autoConvertToBestUnit()), actionCollection(), "auto_convert_to_best_unit"); + ActionAutoConvertToBestUnit->setExclusiveGroup("group_auto_conversion"); + ActionAngleUnitDegrees = new KRadioAction(i18n("Degrees"), 0, this, SLOT(angleUnitDegrees()), actionCollection(), "angle_unit_degrees"); + ActionAngleUnitDegrees->setExclusiveGroup("group_angle_unit"); + ActionAngleUnitRadians = new KRadioAction(i18n("Radians"), 0, this, SLOT(angleUnitRadians()), actionCollection(), "angle_unit_radians"); + ActionAngleUnitRadians->setExclusiveGroup("group_angle_unit"); + ActionAngleUnitGradians = new KRadioAction(i18n("Gradians"), 0, this, SLOT(angleUnitGradians()), actionCollection(), "angle_unit_gradians"); + ActionAngleUnitGradians->setExclusiveGroup("group_angle_unit"); + ActionAngleUnitNone = new KRadioAction(i18n("None"), 0, this, SLOT(angleUnitNone()), actionCollection(), "angle_unit_none"); + ActionAngleUnitNone->setExclusiveGroup("group_angle_unit"); + ActionAbbreviateNames = new KToggleAction(i18n("Abbreviate Names"), 0, actionCollection(), "abbreviate_names"); + QObject::connect(ActionAbbreviateNames, SIGNAL(toggled(bool)), this, SLOT(abbreviateNames(bool))); + ActionEnableVariables = new KToggleAction(i18n("Enable Variables"), 0, actionCollection(), "enable_variables"); + QObject::connect(ActionEnableVariables, SIGNAL(toggled(bool)), this, SLOT(enableVariables(bool))); + ActionEnableFunctions = new KToggleAction(i18n("Enable Functions"), 0, actionCollection(), "enable_functions"); + QObject::connect(ActionEnableFunctions, SIGNAL(toggled(bool)), this, SLOT(enableFunctions(bool))); + ActionEnableUnits = new KToggleAction(i18n("Enable Units"), 0, actionCollection(), "enable_units"); + QObject::connect(ActionEnableUnits, SIGNAL(toggled(bool)), this, SLOT(enableUnits(bool))); + ActionEnableUnknowns = new KToggleAction(i18n("Enable Unknowns"), 0, actionCollection(), "enable_unknowns"); + QObject::connect(ActionEnableUnknowns, SIGNAL(toggled(bool)), this, SLOT(enableUnknowns(bool))); + ActionCalculateVariables = new KToggleAction(i18n("Calculate Variables"), 0, actionCollection(), "calculate_variables"); + QObject::connect(ActionCalculateVariables, SIGNAL(toggled(bool)), this, SLOT(calculateVariables(bool))); + ActionAllowComplexResult = new KToggleAction(i18n("Allow Complex Result"), 0, actionCollection(), "allow_complex_result"); + QObject::connect(ActionAllowComplexResult, SIGNAL(toggled(bool)), this, SLOT(allowComplexResult(bool))); + ActionAllowInfiniteResult = new KToggleAction(i18n("Allow Infinite Result"), 0, actionCollection(), "allow_infinite_result"); + QObject::connect(ActionAllowInfiniteResult, SIGNAL(toggled(bool)), this, SLOT(allowInfiniteResult(bool))); + ActionApproximationTryExact = new KRadioAction(i18n("Try Exact"), 0, this, SLOT(approximationTryExact()), actionCollection(), "approximation_try_exact"); + ActionApproximationTryExact->setExclusiveGroup("group_approximation"); + ActionApproximationAlwaysExact = new KRadioAction(i18n("Always Exact"), 0, this, SLOT(approximationAlwaysExact()), actionCollection(), "approximation_always_exact"); + ActionApproximationAlwaysExact->setExclusiveGroup("group_approximation"); + ActionApproximationApproximate = new KRadioAction(i18n("Approximate"), 0, this, SLOT(approximationApproximate()), actionCollection(), "approximation_approximate"); + ActionApproximationApproximate->setExclusiveGroup("group_approximation"); + ActionAssumptionTypeUnknown = new KRadioAction(i18n("Unknown"), 0, this, SLOT(assumptionTypeUnknown()), actionCollection(), "assumption_type_unknown"); + ActionAssumptionTypeUnknown->setExclusiveGroup("group_assumption_type"); + ActionAssumptionTypeNonMatrix = new KRadioAction(i18n("Not Matrix"), 0, this, SLOT(assumptionTypeNonMatrix()), actionCollection(), "assumption_type_nonmatrix"); + ActionAssumptionTypeNonMatrix->setExclusiveGroup("group_assumption_type"); + ActionAssumptionTypeNumber = new KRadioAction(i18n("Number"), 0, this, SLOT(assumptionTypeNumber()), actionCollection(), "assumption_type_number"); + ActionAssumptionTypeNumber->setExclusiveGroup("group_assumption_type"); + ActionAssumptionTypeComplex = new KRadioAction(i18n("Complex"), 0, this, SLOT(assumptionTypeComplex()), actionCollection(), "assumption_type_complex"); + ActionAssumptionTypeComplex->setExclusiveGroup("group_assumption_type"); + ActionAssumptionTypeReal = new KRadioAction(i18n("Real"), 0, this, SLOT(assumptionTypeReal()), actionCollection(), "assumption_type_real"); + ActionAssumptionTypeReal->setExclusiveGroup("group_assumption_type"); + ActionAssumptionTypeRational = new KRadioAction(i18n("Rational"), 0, this, SLOT(assumptionTypeRational()), actionCollection(), "assumption_type_rational"); + ActionAssumptionTypeRational->setExclusiveGroup("group_assumption_type"); + ActionAssumptionTypeInteger = new KRadioAction(i18n("Integer"), 0, this, SLOT(assumptionTypeInteger()), actionCollection(), "assumption_type_integer"); + ActionAssumptionTypeInteger->setExclusiveGroup("group_assumption_type"); + ActionAssumptionSignUnknown = new KRadioAction(i18n("Unknown"), 0, this, SLOT(assumptionSignUnknown()), actionCollection(), "assumption_sign_unknown"); + ActionAssumptionSignUnknown->setExclusiveGroup("group_assumption_sign"); + ActionAssumptionSignNonZero = new KRadioAction(i18n("Non-Zero"), 0, this, SLOT(assumptionSignNonZero()), actionCollection(), "assumption_sign_non_zero"); + ActionAssumptionSignNonZero->setExclusiveGroup("group_assumption_sign"); + ActionAssumptionSignPositive = new KRadioAction(i18n("Positive"), 0, this, SLOT(assumptionSignPositive()), actionCollection(), "assumption_sign_positive"); + ActionAssumptionSignPositive->setExclusiveGroup("group_assumption_sign"); + ActionAssumptionSignNonNegative = new KRadioAction(i18n("Non-Negative"), 0, this, SLOT(assumptionSignNonNegative()), actionCollection(), "assumption_sign_non_negative"); + ActionAssumptionSignNonNegative->setExclusiveGroup("group_assumption_sign"); + ActionAssumptionSignNegative = new KRadioAction(i18n("Negative"), 0, this, SLOT(assumptionSignNegative()), actionCollection(), "assumption_sign_negative"); + ActionAssumptionSignNegative->setExclusiveGroup("group_assumption_sign"); + ActionAssumptionSignNonPositive = new KRadioAction(i18n("Non-Positive"), 0, this, SLOT(assumptionSignNonPositive()), actionCollection(), "assumption_sign_non_positive"); + ActionAssumptionSignNonPositive->setExclusiveGroup("group_assumption_sign"); + ActionNonZeroDenominators = new KToggleAction(i18n("Non-Zero Denominators"), 0, actionCollection(), "non_zero_denominators"); + QObject::connect(ActionNonZeroDenominators, SIGNAL(toggled(bool)), this, SLOT(nonZeroDenominators(bool))); + ActionWarnAboutDenominatorsAssumedNonZero = new KToggleAction(i18n("Warn About Denominators Assumed Non-Zero"), 0, actionCollection(), "warn_about_denominators_assumed_nonzero"); + QObject::connect(ActionWarnAboutDenominatorsAssumedNonZero, SIGNAL(toggled(bool)), this, SLOT(warnAboutDenominatorsAssumedNonZero(bool))); + ActionAlgebraicModeSimplify = new KRadioAction(i18n("Simplify"), 0, this, SLOT(algebraicModeSimplify()), actionCollection(), "algebraic_mode_simplify"); + ActionAlgebraicModeSimplify->setExclusiveGroup("group_alebraic_mode"); + ActionAlgebraicModeFactorize = new KRadioAction(i18n("Factorize"), 0, this, SLOT(algebraicModeFactorize()), actionCollection(), "algebraic_mode_factorize"); + ActionAlgebraicModeFactorize->setExclusiveGroup("group_alebraic_mode"); + ActionAlgebraicModeNone = new KRadioAction(i18n("None"), 0, this, SLOT(algebraicModeNone()), actionCollection(), "algebraic_mode_none"); + ActionAlgebraicModeNone->setExclusiveGroup("group_alebraic_mode"); + ActionReadPrecision = new KToggleAction(i18n("Read Precision"), 0, actionCollection(), "read_precision"); + QObject::connect(ActionReadPrecision, SIGNAL(toggled(bool)), this, SLOT(readPrecision(bool))); + ActionLimitImplicitMultiplication = new KToggleAction(i18n("Limit Implicit Multiplication"), 0, actionCollection(), "limit_implicit_multiplication"); + QObject::connect(ActionLimitImplicitMultiplication, SIGNAL(toggled(bool)), this, SLOT(limitImplicitMultiplication(bool))); + ActionRPNMode = new KToggleAction(i18n("RPN Mode"), CTRL+Key_R, actionCollection(), "rpn_mode"); + QObject::connect(ActionRPNMode, SIGNAL(toggled(bool)), this, SLOT(rpnMode(bool))); + ActionRPNSyntax = new KToggleAction(i18n("RPN Syntax"), 0, actionCollection(), "rpn_syntax"); + QObject::connect(ActionRPNSyntax, SIGNAL(toggled(bool)), this, SLOT(rpnSyntax(bool))); + ActionPrecision = new KAction(i18n("Precision"), 0, this, SLOT(precision()), actionCollection(), "precision"); + ActionDecimals = new KAction(i18n("Decimals"), 0, this, SLOT(decimals()), actionCollection(), "decimals"); + ActionSaveModeAs = new KAction(i18n("Save Mode..."), "filesave", 0, this, SLOT(saveModeAs()), actionCollection(), "save_mode_as"); + ActionDeleteMode = new KAction(i18n("Delete Mode..."), "editdelete", 0, this, SLOT(deleteMode()), actionCollection(), "delete_mode"); + ActionDeleteMode->setEnabled(modes.size() > 2); + ActionSaveMode = new KAction(i18n("Save Default Mode"), "filesave", 0, this, SLOT(saveMode()), actionCollection(), "save_mode"); + ActionClearStack = new KAction(i18n("Clear Stack"), "view_remove", 0, this, SLOT(clearStack()), actionCollection(), "clear_stack"); + ActionDeleteRegister = new KAction(i18n("Delete"), "editdelete", 0, this, SLOT(deleteRegister()), actionCollection(), "delete_register"); + ActionEditRegister = new KAction(i18n("Edit"), "edit", 0, this, SLOT(editRegister()), actionCollection(), "edit_register"); + + new KAction(i18n("Exp RPN Operation"), CTRL+SHIFT+Key_E, this, SLOT(insertExp()), actionCollection(), "rpn_exp10"); + + setModeActions(); + +} +void KQalculate::setAssumptionsMenu() { + switch(CALCULATOR->defaultAssumptions()->sign()) { + case ASSUMPTION_SIGN_POSITIVE: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignPositive); break;} + case ASSUMPTION_SIGN_NONPOSITIVE: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignNonPositive); break;} + case ASSUMPTION_SIGN_NEGATIVE: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignNegative); break;} + case ASSUMPTION_SIGN_NONNEGATIVE: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignNonNegative); break;} + case ASSUMPTION_SIGN_NONZERO: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignNonZero); break;} + default: {SET_TOGGLE_ACTION_ON(ActionAssumptionSignUnknown); } + } + switch(CALCULATOR->defaultAssumptions()->type()) { + case ASSUMPTION_TYPE_INTEGER: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeInteger); break;} + case ASSUMPTION_TYPE_RATIONAL: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeRational); break;} + case ASSUMPTION_TYPE_COMPLEX: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeComplex); break;} + case ASSUMPTION_TYPE_NUMBER: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeNumber); break;} + case ASSUMPTION_TYPE_REAL: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeReal); break;} + case ASSUMPTION_TYPE_NONMATRIX: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeNonMatrix); break;} + default: {SET_TOGGLE_ACTION_ON(ActionAssumptionTypeUnknown); } + } +} +void KQalculate::setModeActions() { + + SET_TOGGLE_ACTION(ActionAllowComplexResult, evalops.allow_complex) + SET_TOGGLE_ACTION(ActionAllowInfiniteResult, evalops.allow_infinite) + SET_TOGGLE_ACTION(ActionEnableVariables, evalops.parse_options.variables_enabled) + SET_TOGGLE_ACTION(ActionEnableFunctions, evalops.parse_options.functions_enabled) + SET_TOGGLE_ACTION(ActionEnableUnits, evalops.parse_options.units_enabled) + SET_TOGGLE_ACTION(ActionEnableUnknowns, evalops.parse_options.unknowns_enabled) + SET_TOGGLE_ACTION(ActionCalculateVariables, evalops.calculate_variables) + SET_TOGGLE_ACTION(ActionReadPrecision, evalops.parse_options.read_precision != DONT_READ_PRECISION) + SET_TOGGLE_ACTION(ActionLimitImplicitMultiplication, evalops.parse_options.limit_implicit_multiplication) + SET_TOGGLE_ACTION(ActionRPNSyntax, evalops.parse_options.rpn) + SET_TOGGLE_ACTION(ActionRPNMode, rpn_mode) + SET_TOGGLE_ACTION(ActionNonZeroDenominators, evalops.assume_denominators_nonzero) + SET_TOGGLE_ACTION(ActionWarnAboutDenominatorsAssumedNonZero, evalops.warn_about_denominators_assumed_nonzero) + SET_TOGGLE_ACTION(ActionAbbreviateNames, printops.abbreviate_names) + SET_TOGGLE_ACTION(ActionIndicateInfiniteSeries, printops.indicate_infinite_series) + SET_TOGGLE_ACTION(ActionSortMinusLast, printops.sort_options.minus_last) + SET_TOGGLE_ACTION(ActionNegativeExponents, printops.negative_exponents) + SET_TOGGLE_ACTION(ActionShowEndingZeroes, printops.show_ending_zeroes) + SET_TOGGLE_ACTION(ActionRoundHalfwayNumbersToEven, printops.round_halfway_to_even) + SET_TOGGLE_ACTION(ActionEnablePrefixes, printops.use_unit_prefixes) + SET_TOGGLE_ACTION(ActionEnableUseOfAllPrefixes, printops.use_all_prefixes) + SET_TOGGLE_ACTION(ActionEnableDenominatorPrefixes, printops.use_denominator_prefix) + SET_TOGGLE_ACTION(ActionPlaceUnitsSeparately, printops.place_units_separately) + + kpExact->blockSignals(true); + switch(evalops.approximation) { + case APPROXIMATION_EXACT: { + SET_TOGGLE_ACTION_ON(ActionApproximationAlwaysExact); + kpExact->setOn(true); + break; + } + case APPROXIMATION_TRY_EXACT: { + SET_TOGGLE_ACTION_ON(ActionApproximationTryExact); + kpExact->setOn(false); + break; + } + case APPROXIMATION_APPROXIMATE: { + SET_TOGGLE_ACTION_ON(ActionApproximationApproximate); + kpExact->setOn(false); + break; + } + } + kpExact->blockSignals(false); + switch(evalops.auto_post_conversion) { + case POST_CONVERSION_BEST: { + SET_TOGGLE_ACTION_ON(ActionAutoConvertToBestUnit); + break; + } + case POST_CONVERSION_BASE: { + SET_TOGGLE_ACTION_ON(ActionAutoConvertToBaseUnits); + break; + } + default: { + SET_TOGGLE_ACTION_ON(ActionAutoNoConversion); + } + } + kpAngleGroup->blockSignals(true); + switch(evalops.parse_options.angle_unit) { + case ANGLE_UNIT_DEGREES: { + SET_TOGGLE_ACTION_ON(ActionAngleUnitDegrees); + kpAngleGroup->setButton(0); + break; + } + case ANGLE_UNIT_RADIANS: { + SET_TOGGLE_ACTION_ON(ActionAngleUnitRadians); + kpAngleGroup->setButton(1); + break; + } + case ANGLE_UNIT_GRADIANS: { + SET_TOGGLE_ACTION_ON(ActionAngleUnitGradians); + kpAngleGroup->setButton(2); + break; + } + default: { + SET_TOGGLE_ACTION_ON(ActionAngleUnitNone); + kpAngleGroup->setButton(3); + } + } + kpAngleGroup->blockSignals(false); + + kpBaseCombo->blockSignals(true); + switch(printops.base) { + case BASE_BINARY: { + SET_TOGGLE_ACTION_ON(ActionNumberBaseBinary); + kpBaseCombo->setCurrentItem(0); + break; + } + case BASE_OCTAL: { + SET_TOGGLE_ACTION_ON(ActionNumberBaseOctal); + kpBaseCombo->setCurrentItem(1); + break; + } + case BASE_DECIMAL: { + SET_TOGGLE_ACTION_ON(ActionNumberBaseDecimal); + kpBaseCombo->setCurrentItem(2); + break; + } + case BASE_HEXADECIMAL: { + SET_TOGGLE_ACTION_ON(ActionNumberBaseHexadecimal); + kpBaseCombo->setCurrentItem(3); + break; + } + case BASE_ROMAN_NUMERALS: { + SET_TOGGLE_ACTION_ON(ActionNumberBaseRomanNumerals); + kpBaseCombo->setCurrentItem(6); + break; + } + case BASE_SEXAGESIMAL: { + SET_TOGGLE_ACTION_ON(ActionNumberBaseSexagesimal); + kpBaseCombo->setCurrentItem(4); + break; + } + case BASE_TIME: { + SET_TOGGLE_ACTION_ON(ActionNumberBaseTimeFormat); + kpBaseCombo->setCurrentItem(5); + break; + } + default: { + SET_TOGGLE_ACTION_ON(ActionNumberBaseOther); + kpBaseCombo->setCurrentItem(7); + } + } + kpBaseCombo->blockSignals(false); + + kpNumericCombo->blockSignals(true); + switch(printops.min_exp) { + case EXP_PRECISION: { + SET_TOGGLE_ACTION_ON(ActionNumericalDisplayNormal); + kpNumericCombo->setCurrentItem(0); + break; + } + case EXP_BASE_3: { + SET_TOGGLE_ACTION_ON(ActionNumericalDisplayEngineering); + kpNumericCombo->setCurrentItem(1); + break; + } + case EXP_SCIENTIFIC: { + SET_TOGGLE_ACTION_ON(ActionNumericalDisplayScientific); + kpNumericCombo->setCurrentItem(2); + break; + } + case EXP_PURE: { + SET_TOGGLE_ACTION_ON(ActionNumericalDisplayPurelyScientific); + kpNumericCombo->setCurrentItem(3); + break; + } + case EXP_NONE: { + SET_TOGGLE_ACTION_ON(ActionNumericalDisplaySimple); + kpNumericCombo->setCurrentItem(4); + break; + } + } + kpNumericCombo->blockSignals(false); + + kpFraction->blockSignals(true); + switch (printops.number_fraction_format) { + case FRACTION_DECIMAL: { + SET_TOGGLE_ACTION_ON(ActionFractionalDisplayDecimal); + kpFraction->setOn(false); + break; + } + case FRACTION_DECIMAL_EXACT: { + SET_TOGGLE_ACTION_ON(ActionFractionalDisplayDecimalTryExact); + kpFraction->setOn(false); + break; + } + case FRACTION_COMBINED: { + SET_TOGGLE_ACTION_ON(ActionFractionalDisplayCombined); + kpFraction->setOn(true); + break; + } + case FRACTION_FRACTIONAL: { + SET_TOGGLE_ACTION_ON(ActionFractionalDisplayFraction); + kpFraction->setOn(true); + break; + } + } + kpFraction->blockSignals(false); + + setAssumptionsMenu(); + switch(evalops.structuring) { + case STRUCTURING_SIMPLIFY: {SET_TOGGLE_ACTION_ON(ActionAlgebraicModeSimplify); break;} + case STRUCTURING_FACTORIZE: {SET_TOGGLE_ACTION_ON(ActionAlgebraicModeFactorize); break;} + default: {SET_TOGGLE_ACTION_ON(ActionAlgebraicModeNone); } + } + +} + +#define TEXT_TAGS "" +#define TEXT_TAGS_END "" +#define TEXT_TAGS_SMALL "" +#define TEXT_TAGS_SMALL_END "" +#define TEXT_TAGS_XSMALL "" +#define TEXT_TAGS_XSMALL_END "" + +#define STR_MARKUP_ADD_SMALL(str, str_add) if(ips.power_depth > 0) {str += TEXT_TAGS ""; str += str_add; str += "" TEXT_TAGS_END;} else {str += TEXT_TAGS_SMALL; str += str_add; str += TEXT_TAGS_SMALL_END;} + +#define STR_MARKUP_ADD(str, str_add) if(ips.power_depth > 0) {str += TEXT_TAGS ""; str += str_add; str += "" TEXT_TAGS_END;} else {str += str_add;} + +#define STR_MARKUP_PREPEND(str, str_add) QString str_prepend; if(ips.power_depth > 0) {str_prepend += TEXT_TAGS ""; str_prepend += str_add; str_prepend += "" TEXT_TAGS_END;} else {str_prepend += str_add;} str.prepend(str_prepend); + +#define STR_MARKUP_BEGIN(str) if(ips.power_depth > 0) {str += TEXT_TAGS "";} +#define STR_MARKUP_END(str) if(ips.power_depth > 0) {str +="" TEXT_TAGS_END;} + +#define STR_MARKUP_BEGIN_SMALL(str) if(ips.power_depth > 0) {str += TEXT_TAGS_SMALL "";} else {str += TEXT_TAGS_SMALL;} +#define STR_MARKUP_END_SMALL(str) if(ips.power_depth > 0) {str +="" TEXT_TAGS_SMALL_END;} else {str += TEXT_TAGS_SMALL_END;} + +#define STR_MARKUP_BEGIN_CURSIVE(str) if(ips.power_depth > 0) {str += TEXT_TAGS "";} else {str += "";} +#define STR_MARKUP_END_CURSIVE(str) if(ips.power_depth > 0) {str +="" TEXT_TAGS_END;} else {str += "";} + +QString draw_structure(MathStructure &m, const QFont &font, const QColorGroup &cg, PrintOptions po = default_print_options, InternalPrintStruct ips = top_ips, bool in_matrix = false) { + + if(ips.depth == 0 && po.is_approximate) *po.is_approximate = false; + + QString mstr; + + InternalPrintStruct ips_n = ips; + if(m.isApproximate()) ips_n.parent_approximate = true; + if(m.precision() > 0 && (ips_n.parent_precision < 1 || m.precision() < ips_n.parent_precision)) ips_n.parent_precision = m.precision(); + switch(m.type()) { + case STRUCT_NUMBER: { + string exp = ""; + bool exp_minus; + ips_n.exp = &exp; + ips_n.exp_minus = &exp_minus; + STR_MARKUP_BEGIN(mstr); + mstr += m.number().print(po, ips_n).c_str(); + if(!exp.empty()) { + if(po.lower_case_e) { + mstr += "e"; + } else { + STR_MARKUP_ADD_SMALL(mstr, "E"); + } + if(exp_minus) { + mstr += "-"; + } + mstr += exp.c_str(); + } + if(po.base != BASE_DECIMAL && po.base != BASE_HEXADECIMAL && po.base > 0 && po.base <= 36) { + if(ips.power_depth == 0) { + mstr += ""; + mstr += QString::number(po.base); + mstr += ""; + } else { + mstr += TEXT_TAGS_SMALL ""; + mstr += QString::number(po.base); + mstr += "" TEXT_TAGS_SMALL_END; + } + } + STR_MARKUP_END(mstr); + break; + } + case STRUCT_SYMBOLIC: { + result_parts.push_back(m); + mstr = ""; + STR_MARKUP_BEGIN_CURSIVE(mstr); + mstr += m.symbol().c_str(); + STR_MARKUP_END_CURSIVE(mstr); + mstr += ""; + mstr += ""; + break; + } + case STRUCT_ADDITION: { + + ips_n.depth++; + + vector terms; + vector do_space; + for(size_t i = 0; i < m.size(); i++) { + if(m[i].type() == STRUCT_NEGATE && i > 0) { + ips_n.wrap = m[i][0].needsParenthesis(po, ips_n, m, i + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + terms.push_back(draw_structure(m[i][0], font, cg, po, ips_n)); + } else { + ips_n.wrap = m[i].needsParenthesis(po, ips_n, m, i + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + terms.push_back(draw_structure(m[i], font, cg, po, ips_n)); + } + do_space.push_back(!terms[i].endsWith("valign=\"middle\">")); + } + for(size_t i = 0; i < terms.size(); i++) { + if(i > 0) { + if(do_space[i - 1]) STR_MARKUP_ADD(mstr, " "); + if(m[i].type() == STRUCT_NEGATE) { + if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_MINUS, po.can_display_unicode_string_arg))) { + STR_MARKUP_ADD(mstr, SIGN_MINUS); + } else { + STR_MARKUP_ADD(mstr, "-"); + } + } else { + STR_MARKUP_ADD(mstr, "+"); + } + if(do_space[i]) STR_MARKUP_ADD(mstr, " "); + } + mstr += terms[i]; + } + break; + } + case STRUCT_NEGATE: { + + ips_n.depth++; + + ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_MINUS, po.can_display_unicode_string_arg))) { + STR_MARKUP_ADD(mstr, SIGN_MINUS); + } else { + STR_MARKUP_ADD(mstr, "-"); + } + mstr += draw_structure(m[0], font, cg, po, ips_n); + break; + } + case STRUCT_MULTIPLICATION: { + + ips_n.depth++; + + QString mul_str; + if(po.use_unicode_signs && po.multiplication_sign == MULTIPLICATION_SIGN_DOT && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_MULTIDOT, po.can_display_unicode_string_arg))) { + STR_MARKUP_ADD(mul_str, SIGN_MULTIDOT); + } else if(po.use_unicode_signs && po.multiplication_sign == MULTIPLICATION_SIGN_DOT && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_MULTIBULLET, po.can_display_unicode_string_arg))) { + STR_MARKUP_ADD(mul_str, SIGN_MULTIBULLET); + } else if(po.use_unicode_signs && po.multiplication_sign == MULTIPLICATION_SIGN_DOT && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_SMALLCIRCLE, po.can_display_unicode_string_arg))) { + STR_MARKUP_ADD(mul_str, SIGN_SMALLCIRCLE); + } else if(po.use_unicode_signs && po.multiplication_sign == MULTIPLICATION_SIGN_X && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_MULTIPLICATION, po.can_display_unicode_string_arg))) { + STR_MARKUP_ADD(mul_str, SIGN_MULTIPLICATION); + } else { + STR_MARKUP_ADD(mul_str, "*"); + } + + bool par_prev = false; + vector nm; + vector terms; + vector do_space; + for(size_t i = 0; i < m.size(); i++) { + ips_n.wrap = m[i].needsParenthesis(po, ips_n, m, i + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + terms.push_back(draw_structure(m[i], font, cg, po, ips_n)); + if(!po.short_multiplication && i > 0) { + nm.push_back(-1); + } else if(i > 0) { + nm.push_back(m[i].neededMultiplicationSign(po, ips_n, m, i + 1, ips_n.wrap || (m[i].isPower() && m[i][0].needsParenthesis(po, ips_n, m[i], 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0)), par_prev, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0)); + } else { + nm.push_back(-1); + } + do_space.push_back(!terms[i].endsWith("valign=\"middle\">")); + par_prev = ips_n.wrap; + } + for(size_t i = 0; i < terms.size(); i++) { + if(!po.short_multiplication && i > 0) { + if(do_space[i - 1]) STR_MARKUP_ADD(mstr, " "); + mstr += mul_str; + if(do_space[i]) STR_MARKUP_ADD(mstr, " "); + } else if(i > 0) { + switch(nm[i]) { + case MULTIPLICATION_SIGN_SPACE: { + if(do_space[i - 1] && do_space[i]) STR_MARKUP_ADD(mstr, " "); + break; + } + case MULTIPLICATION_SIGN_OPERATOR: { + if(do_space[i - 1]) STR_MARKUP_ADD(mstr, " "); + mstr += mul_str; + if(do_space[i]) STR_MARKUP_ADD(mstr, " "); + break; + } + case MULTIPLICATION_SIGN_OPERATOR_SHORT: { + mstr += mul_str; + break; + } + } + } + mstr += terms[i]; + } + break; + } + case STRUCT_INVERSE: {} + case STRUCT_DIVISION: { + + ips_n.depth++; + ips_n.division_depth++; + + bool flat = ips.division_depth > 0 || ips.power_depth > 0; + if(!flat && po.place_units_separately) { + flat = true; + size_t i = 0; + if(m.isDivision()) { + i = 1; + } + if(m[i].isMultiplication()) { + for(size_t i2 = 0; i2 < m[i].size(); i2++) { + if(!m[i][i2].isUnit_exp()) { + flat = false; + break; + } + } + } else if(!m[i].isUnit_exp()) { + flat = false; + } + if(flat) { + ips_n.division_depth--; + } + } + QString num_str, den_str; + if(m.type() == STRUCT_DIVISION) { + ips_n.wrap = (!m[0].isDivision() || !flat || ips.division_depth > 0 || ips.power_depth > 0) && m[0].needsParenthesis(po, ips_n, m, 1, flat, ips.power_depth > 0); + num_str = draw_structure(m[0], font, cg, po, ips_n); + } else { + MathStructure onestruct(1, 1); + ips_n.wrap = false; + num_str = draw_structure(onestruct, font, cg, po, ips_n); + } + if(m.type() == STRUCT_DIVISION) { + ips_n.wrap = m[1].needsParenthesis(po, ips_n, m, 2, flat, ips.power_depth > 0); + den_str = draw_structure(m[1], font, cg, po, ips_n); + } else { + ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 2, flat, ips.power_depth > 0); + den_str = draw_structure(m[0], font, cg, po, ips_n); + } + + if(flat) { + QString div_str; + if(po.use_unicode_signs && po.division_sign == DIVISION_SIGN_DIVISION && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_DIVISION, po.can_display_unicode_string_arg))) { + STR_MARKUP_ADD(div_str, " " SIGN_DIVISION " "); + } else if(po.use_unicode_signs && po.division_sign == DIVISION_SIGN_DIVISION_SLASH && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_DIVISION_SLASH, po.can_display_unicode_string_arg))) { + STR_MARKUP_ADD(div_str, " " SIGN_DIVISION_SLASH " "); + } else { + STR_MARKUP_ADD(div_str, " / "); + } + mstr = num_str; + mstr += div_str; + mstr += den_str; + } else { + + int den_w, num_w, w = 0, h = 0; + + num_str.prepend(TEXT_TAGS); + num_str += TEXT_TAGS_END; + den_str.prepend(TEXT_TAGS); + den_str += TEXT_TAGS_END; + + QSimpleRichText text_r(num_str, font); text_r.setWidth(10000); + num_w = text_r.widthUsed(); + QSimpleRichText text_rn(den_str, font); text_rn.setWidth(10000); + den_w = text_rn.widthUsed(); + + w = den_w; + if(num_w > w) w = num_w; + w += 2; + + QSimpleRichText textsmall("X", font); + h = (int) (textsmall.height() / 1.5); + h += h % 2; + + string filename = getLocalDir(); + if(saved_divisionline_height != h) { + + QPixmap *pixmap = new QPixmap(10, h); + pixmap->fill(cg.background()); + QPainter p(pixmap); + QPen ppen = p.pen(); + ppen.setColor(cg.foreground()); + p.setPen(ppen); + p.drawLine(0, h / 2, 10, h / 2); + p.drawLine(0, h / 2 + 1, 10, h / 2 + 1); + p.flush(); + p.end(); + + pixmap->setMask(pixmap->createHeuristicMask()); + mkdir(filename.c_str(), S_IRWXU); + filename += "tmp/"; + mkdir(filename.c_str(), S_IRWXU); + filename += "divline.png"; + pixmap->save(filename.c_str(), "PNG", 100); + + delete pixmap; + + saved_divisionline_height = h; + + } else { + + filename += "tmp/divline.png"; + + } + + mstr = TEXT_TAGS_END; + mstr = ""; + mstr += num_str; + mstr += "

"; + mstr += den_str; + mstr += ""; + mstr += TEXT_TAGS; + + } + break; + } + case STRUCT_POWER: { + + ips_n.depth++; + + ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + + ips_n.division_depth++; + mstr += draw_structure(m[0], font, cg, po, ips_n); + ips_n.division_depth--; + + ips_n.power_depth++; + ips_n.wrap = m[1].needsParenthesis(po, ips_n, m, 2, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + + PrintOptions po2 = po; + po2.show_ending_zeroes = false; + if(ips.power_depth > 0) { + mstr += TEXT_TAGS "" "^" "" TEXT_TAGS_END; + mstr += draw_structure(m[1], font, cg, po2, ips_n); + } else { + mstr += draw_structure(m[1], font, cg, po2, ips_n); + } + + break; + } + case STRUCT_LOGICAL_AND: { + if(!po.preserve_format && m.size() == 2 && m[0].isComparison() && m[1].isComparison() && m[0].comparisonType() != COMPARISON_EQUALS && m[0].comparisonType() != COMPARISON_NOT_EQUALS && m[1].comparisonType() != COMPARISON_EQUALS && m[1].comparisonType() != COMPARISON_NOT_EQUALS && m[0][0] == m[1][0]) { + + ips_n.depth++; + + bool do_space = true; + QString tstr; + ips_n.wrap = m[0][1].needsParenthesis(po, ips_n, m[0], 2, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + tstr = draw_structure(m[0][1], font, cg, po, ips_n); + do_space = !tstr.endsWith("valign=\"middle\">"); + mstr += tstr; + STR_MARKUP_BEGIN(mstr); + if(do_space) mstr += " "; + switch(m[0].comparisonType()) { + case COMPARISON_LESS: { + mstr += ">"; + break; + } + case COMPARISON_GREATER: { + mstr += "<"; + break; + } + case COMPARISON_EQUALS_LESS: { + if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_GREATER_OR_EQUAL, po.can_display_unicode_string_arg))) { + mstr += SIGN_GREATER_OR_EQUAL; + } else { + mstr += ">="; + } + break; + } + case COMPARISON_EQUALS_GREATER: { + if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_LESS_OR_EQUAL, po.can_display_unicode_string_arg))) { + mstr += SIGN_LESS_OR_EQUAL; + } else { + mstr += "<="; + } + break; + } + default: {} + } + + ips_n.wrap = m[0][0].needsParenthesis(po, ips_n, m[0], 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + tstr = draw_structure(m[0][0], font, cg, po, ips_n); + do_space = !tstr.endsWith("valign=\"middle\">"); + if(do_space) mstr += " "; + STR_MARKUP_END(mstr); + mstr += tstr; + STR_MARKUP_BEGIN(mstr); + if(do_space) mstr += " "; + + switch(m[1].comparisonType()) { + case COMPARISON_GREATER: { + mstr += ">"; + break; + } + case COMPARISON_LESS: { + mstr += "<"; + break; + } + case COMPARISON_EQUALS_GREATER: { + if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_GREATER_OR_EQUAL, po.can_display_unicode_string_arg))) { + mstr += SIGN_GREATER_OR_EQUAL; + } else { + mstr += ">="; + } + break; + } + case COMPARISON_EQUALS_LESS: { + if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_LESS_OR_EQUAL, po.can_display_unicode_string_arg))) { + mstr += SIGN_LESS_OR_EQUAL; + } else { + mstr += "<="; + } + break; + } + default: {} + } + + ips_n.wrap = m[1][1].needsParenthesis(po, ips_n, m[1], 2, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + tstr = draw_structure(m[1][1], font, cg, po, ips_n); + do_space = !tstr.endsWith("valign=\"middle\">"); + if(do_space) mstr += " "; + STR_MARKUP_END(mstr); + mstr += tstr; + + break; + } + } + case STRUCT_COMPARISON: {} + case STRUCT_LOGICAL_XOR: {} + case STRUCT_LOGICAL_OR: {} + case STRUCT_BITWISE_AND: {} + case STRUCT_BITWISE_XOR: {} + case STRUCT_BITWISE_OR: { + + ips_n.depth++; + + QString str; + if(m.type() == STRUCT_COMPARISON) { + switch(m.comparisonType()) { + case COMPARISON_EQUALS: { + break; + } + case COMPARISON_NOT_EQUALS: { + if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_NOT_EQUAL, po.can_display_unicode_string_arg))) { + str += SIGN_NOT_EQUAL; + } else { + str += "!="; + } + break; + } + case COMPARISON_GREATER: { + str += ">"; + break; + } + case COMPARISON_LESS: { + str += "<"; + break; + } + case COMPARISON_EQUALS_GREATER: { + if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_GREATER_OR_EQUAL, po.can_display_unicode_string_arg))) { + str += SIGN_GREATER_OR_EQUAL; + } else { + str += ">="; + } + break; + } + case COMPARISON_EQUALS_LESS: { + if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_LESS_OR_EQUAL, po.can_display_unicode_string_arg))) { + str += SIGN_LESS_OR_EQUAL; + } else { + str += "<="; + } + break; + } + } + } else if(m.type() == STRUCT_LOGICAL_AND) { + str += ""; + if(po.spell_out_logical_operators) str += i18n("and"); + else str += "&&"; + str += ""; + } else if(m.type() == STRUCT_LOGICAL_OR) { + str += ""; + if(po.spell_out_logical_operators) str += i18n("or"); + else str += "||"; + str += ""; + } else if(m.type() == STRUCT_LOGICAL_XOR) { + str += "XOR"; + } else if(m.type() == STRUCT_BITWISE_AND) { + str += "&"; + } else if(m.type() == STRUCT_BITWISE_OR) { + str += "|"; + } else if(m.type() == STRUCT_BITWISE_XOR) { + str += "XOR"; + } + + bool do_space = true, do_space_prev = true; + QString tstr; + for(size_t i = 0; i < m.size(); i++) { + do_space_prev = do_space; + ips_n.wrap = m[i].needsParenthesis(po, ips_n, m, i + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + tstr = draw_structure(m[i], font, cg, po, ips_n); + do_space = !tstr.endsWith("valign=\"middle\">"); + if(i > 0) { + STR_MARKUP_BEGIN(mstr); + if(do_space_prev) mstr += " "; + if(m.isComparison() && m.comparisonType() == COMPARISON_EQUALS) { + if(ips.depth == 0 && po.use_unicode_signs && (*po.is_approximate || m.isApproximate()) && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_ALMOST_EQUAL, po.can_display_unicode_string_arg))) { + mstr += SIGN_ALMOST_EQUAL; + } else { + mstr += "="; + } + } else { + mstr += str; + } + if(do_space) mstr += " "; + STR_MARKUP_END(mstr); + } + mstr += tstr; + } + break; + } + case STRUCT_BITWISE_NOT: { + + ips_n.depth++; + + STR_MARKUP_BEGIN(mstr); + + mstr += "~"; + + ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + mstr += draw_structure(m[0], font, cg, po, ips_n); + + STR_MARKUP_END(mstr); + + break; + } + case STRUCT_LOGICAL_NOT: { + + ips_n.depth++; + + STR_MARKUP_BEGIN(mstr); + + mstr += "!"; + + ips_n.wrap = m[0].needsParenthesis(po, ips_n, m, 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + mstr += draw_structure(m[0], font, cg, po, ips_n); + + STR_MARKUP_END(mstr); + + break; + } + case STRUCT_VECTOR: { + + ips_n.depth++; + + bool is_matrix = m.isMatrix(); + if(!in_matrix) { + result_parts.push_back(m); + mstr = ""; + } + + if(m.size() == 0) { + STR_MARKUP_ADD(mstr, "( "); + } else { + STR_MARKUP_ADD(mstr, "("); + } + for(size_t index = 0; index < m.size(); index++) { + if(index > 0) { + STR_MARKUP_BEGIN(mstr); + mstr += CALCULATOR->getComma().c_str(); + mstr += " "; + STR_MARKUP_END(mstr); + } + ips_n.wrap = m[index].needsParenthesis(po, ips_n, m, index + 1, ips.division_depth > 0 || ips.power_depth > 0, ips.power_depth > 0); + mstr += draw_structure(m[index], font, cg, po, ips_n, is_matrix); + } + STR_MARKUP_ADD(mstr, ")"); + if(!in_matrix) mstr += ""; + break; + } + case STRUCT_UNIT: { + + result_parts.push_back(m); + mstr = ""; + + STR_MARKUP_BEGIN(mstr); + + QString str; + const ExpressionName *ename = &m.unit()->preferredDisplayName(po.abbreviate_names, po.use_unicode_signs, m.isPlural(), po.use_reference_names, po.can_display_unicode_string_function, po.can_display_unicode_string_arg); + if(m.prefix()) { + str += m.prefix()->name(po.abbreviate_names && ename->abbreviation && (ename->suffix || ename->name.find("_") == string::npos), po.use_unicode_signs, po.can_display_unicode_string_function, po.can_display_unicode_string_arg).c_str(); + } + if(ename->suffix && ename->name.length() > 1) { + size_t i = ename->name.rfind('_'); + bool b = i == string::npos || i == ename->name.length() - 1 || i == 0; + size_t i2 = 1; + if(b) { + if(is_in(NUMBERS, ename->name[ename->name.length() - 1])) { + while(ename->name.length() > i2 + 1 && is_in(NUMBERS, ename->name[ename->name.length() - 1 - i2])) { + i2++; + } + } + str += ename->name.substr(0, ename->name.length() - i2).c_str(); + } else { + str += ename->name.substr(0, i).c_str(); + } + if(ips.power_depth == 0) str += ""; + else str += TEXT_TAGS_SMALL ""; + if(b) str += ename->name.substr(ename->name.length() - i2, i2).c_str(); + else str += ename->name.substr(i + 1, ename->name.length() - (i + 1)).c_str(); + if(ips.power_depth == 0) str += ""; + else str += "" TEXT_TAGS_SMALL_END; + } else { + str += ename->name.c_str(); + } + str.replace("_", " "); + mstr += str; + + STR_MARKUP_END(mstr); + mstr += ""; + mstr += ""; + + break; + } + case STRUCT_VARIABLE: { + + result_parts.push_back(m); + mstr = ""; + if(m.variable() == CALCULATOR->v_i) { + STR_MARKUP_BEGIN(mstr); + } else { + STR_MARKUP_BEGIN_CURSIVE(mstr); + } + + QString str; + const ExpressionName *ename = &m.variable()->preferredDisplayName(po.abbreviate_names, po.use_unicode_signs, false, po.use_reference_names, po.can_display_unicode_string_function, po.can_display_unicode_string_arg); + if(ename->suffix && ename->name.length() > 1) { + size_t i = ename->name.rfind('_'); + bool b = i == string::npos || i == ename->name.length() - 1 || i == 0; + size_t i2 = 1; + if(b) { + if(is_in(NUMBERS, ename->name[ename->name.length() - 1])) { + while(ename->name.length() > i2 + 1 && is_in(NUMBERS, ename->name[ename->name.length() - 1 - i2])) { + i2++; + } + } + str += ename->name.substr(0, ename->name.length() - i2).c_str(); + } else { + str += ename->name.substr(0, i).c_str(); + } + if(ips.power_depth == 0) str += ""; + else str += TEXT_TAGS_SMALL ""; + if(b) str += ename->name.substr(ename->name.length() - i2, i2).c_str(); + else str += ename->name.substr(i + 1, ename->name.length() - (i + 1)).c_str(); + if(ips.power_depth == 0) str += ""; + else str += "" TEXT_TAGS_SMALL_END; + } else { + str += ename->name.c_str(); + } + str.replace("_", " "); + mstr += str; + + if(m.variable() == CALCULATOR->v_i) { + STR_MARKUP_END(mstr); + } else { + STR_MARKUP_END_CURSIVE(mstr); + } + mstr += ""; + /*result_parts.push_back(m); + mstr += "";*/ + break; + } + case STRUCT_FUNCTION: { + + ips_n.depth++; + + result_parts.push_back(m); + mstr = ""; + + STR_MARKUP_BEGIN(mstr); + + QString str; + const ExpressionName *ename = &m.function()->preferredDisplayName(po.abbreviate_names, po.use_unicode_signs, false, po.use_reference_names, po.can_display_unicode_string_function, po.can_display_unicode_string_arg); + if(ename->suffix && ename->name.length() > 1) { + size_t i = ename->name.rfind('_'); + bool b = i == string::npos || i == ename->name.length() - 1 || i == 0; + size_t i2 = 1; + if(b) { + if(is_in(NUMBERS, ename->name[ename->name.length() - 1])) { + while(ename->name.length() > i2 + 1 && is_in(NUMBERS, ename->name[ename->name.length() - 1 - i2])) { + i2++; + } + } + str += ename->name.substr(0, ename->name.length() - i2).c_str(); + } else { + str += ename->name.substr(0, i).c_str(); + } + if(ips.power_depth == 0) str += ""; + else str += TEXT_TAGS_SMALL ""; + if(b) str += ename->name.substr(ename->name.length() - i2, i2).c_str(); + else str += ename->name.substr(i + 1, ename->name.length() - (i + 1)).c_str(); + if(ips.power_depth == 0) str += ""; + else str += "" TEXT_TAGS_SMALL_END; + } else { + str += ename->name.c_str(); + } + str.replace("_", " "); + mstr += str; + + mstr += "("; + STR_MARKUP_END(mstr); + mstr += ""; + + for(size_t index = 0; index < m.size(); index++) { + if(index > 0) { + STR_MARKUP_BEGIN(mstr); + mstr += po.comma().c_str(); + mstr += " "; + STR_MARKUP_END(mstr); + } + mstr += draw_structure(m[index], font, cg, po, ips_n); + } + STR_MARKUP_ADD(mstr, ")"); + + break; + } + case STRUCT_UNDEFINED: { + STR_MARKUP_ADD(mstr, i18n("undefined")); + break; + } + default: { + } + } + if(ips.wrap) { + STR_MARKUP_PREPEND(mstr, "("); + STR_MARKUP_ADD(mstr, ")"); + } + if(ips.depth == 0 && !(m.isComparison() && (!(*po.is_approximate || m.isApproximate()) || (m.comparisonType() == COMPARISON_EQUALS && po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_ALMOST_EQUAL, po.can_display_unicode_string_arg)))))) { + QString equals_str; + if(*po.is_approximate || m.isApproximate()) { + if(po.use_unicode_signs && (!po.can_display_unicode_string_function || (*po.can_display_unicode_string_function) (SIGN_ALMOST_EQUAL, po.can_display_unicode_string_arg))) { + equals_str = SIGN_ALMOST_EQUAL " "; + } else { + equals_str += i18n("approx."); + equals_str += " "; + } + } else { + equals_str = "= "; + } + mstr.prepend(equals_str); + } + if(ips.depth == 0) { + mstr.prepend(TEXT_TAGS); + mstr += TEXT_TAGS_END; + } + + return mstr; + +} + +#define STATUS_SPACE if(b) str += " "; else b = true; + +void KQalculate::update_status_text() { + + QString str; + bool b = false; + + if(evalops.approximation == APPROXIMATION_EXACT) { + STATUS_SPACE + str += i18n("EXACT"); + } else if(evalops.approximation == APPROXIMATION_APPROXIMATE) { + STATUS_SPACE + str += i18n("APPROX"); + } + if(evalops.parse_options.rpn) { + STATUS_SPACE + str += i18n("RPN"); + } + switch(evalops.parse_options.base) { + case BASE_DECIMAL: { + break; + } + case BASE_BINARY: { + STATUS_SPACE + str += i18n("BIN"); + break; + } + case BASE_OCTAL: { + STATUS_SPACE + str += i18n("OCT"); + break; + } + case BASE_HEXADECIMAL: { + STATUS_SPACE + str += i18n("HEX"); + break; + } + case BASE_ROMAN_NUMERALS: { + STATUS_SPACE + str += i18n("ROMAN"); + break; + } + default: { + STATUS_SPACE + str += QString::number(evalops.parse_options.base); + break; + } + } + switch (evalops.parse_options.angle_unit) { + case ANGLE_UNIT_DEGREES: { + STATUS_SPACE + str += i18n("DEG"); + break; + } + case ANGLE_UNIT_RADIANS: { + STATUS_SPACE + str += i18n("RAD"); + break; + } + case ANGLE_UNIT_GRADIANS: { + STATUS_SPACE + str += i18n("GRA"); + break; + } + default: {} + } + if(evalops.parse_options.read_precision != DONT_READ_PRECISION) { + STATUS_SPACE + str += i18n("PREC"); + } + if(!evalops.parse_options.functions_enabled) { + STATUS_SPACE + str += ""; + str += i18n("FUNC"); + str += ""; + } + if(!evalops.parse_options.units_enabled) { + STATUS_SPACE + str += ""; + str += i18n("UNIT"); + str += ""; + } + if(!evalops.parse_options.variables_enabled) { + STATUS_SPACE + str += ""; + str += i18n("VAR"); + str += ""; + } + if(!evalops.allow_infinite) { + STATUS_SPACE + str += ""; + str += i18n("INF"); + str += ""; + } + if(!evalops.allow_complex) { + STATUS_SPACE + str += ""; + str += i18n("CPLX"); + str += ""; + } + str = str.stripWhiteSpace(); + if(b) str += " "; + else str += "  "; + + if(str != statusLabel_r->text()) { + statusLabel_r->setText(str); + qApp->processEvents(); + displayParseStatus(); + } + +} + + +void on_abort_display() { + pthread_cancel(view_thread); + CALCULATOR->restoreState(); + CALCULATOR->clearBuffers(); + b_busy = false; + pthread_create(&view_thread, &view_thread_attr, view_proc, view_pipe_r); +} + +void *view_proc(void *pipe) { + + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + FILE *view_pipe = (FILE*) pipe; + + while(true) { + + bool *do_wrap; + void *x = NULL; + fread(&x, sizeof(void*), 1, view_pipe); + KQalculate *win = (KQalculate*) x; + fread(&x, sizeof(void*), 1, view_pipe); + MathStructure m(*((MathStructure*) x)); + fread(&x, sizeof(void*), 1, view_pipe); + MathStructure *mm = (MathStructure*) x; + fread(&do_wrap, sizeof(bool*), 1, view_pipe); + fread(&x, sizeof(void*), 1, view_pipe); + printops.can_display_unicode_string_arg = (void*) win->historyBrowser; + if(x) { + PrintOptions po; + po.preserve_format = true; + po.show_ending_zeroes = true; + po.lower_case_e = printops.lower_case_e; + po.lower_case_numbers = printops.lower_case_numbers; + po.base_display = printops.base_display; + po.abbreviate_names = false; + po.use_unicode_signs = printops.use_unicode_signs; + po.multiplication_sign = printops.multiplication_sign; + po.division_sign = printops.division_sign; + po.short_multiplication = false; + po.excessive_parenthesis = true; + po.improve_division_multipliers = false; + po.can_display_unicode_string_function = &can_display_unicode_string_function; + po.can_display_unicode_string_arg = (void*) win->statusLabel_l; + po.spell_out_logical_operators = printops.spell_out_logical_operators; + po.restrict_to_parent_precision = false; + MathStructure mp(*((MathStructure*) x)); + fread(&po.is_approximate, sizeof(bool*), 1, view_pipe); + mp.format(po); + parsed_text = mp.print(po).c_str(); + fread(&x, sizeof(void*), 1, view_pipe); + mp.set(*((MathStructure*) x)); + if(!mp.isUndefined()) { + mp.format(po); + parsed_text += CALCULATOR->localToString().c_str(); + parsed_text += mp.print(po).c_str(); + } + } + printops.allow_non_usable = false; + if(mm && m.isMatrix()) { + mm->set(m); + MathStructure mm2(m); + string mstr; + int c = mm->columns(), r = mm->rows(); + for(int index_r = 0; index_r < r; index_r++) { + for(int index_c = 0; index_c < c; index_c++) { + mm->getElement(index_r + 1, index_c + 1)->set(i18n("aborted").ascii()); + } + } + for(int index_r = 0; index_r < r; index_r++) { + for(int index_c = 0; index_c < c; index_c++) { + mm2.getElement(index_r + 1, index_c + 1)->format(printops); + mstr = mm2.getElement(index_r + 1, index_c + 1)->print(printops); + mm->getElement(index_r + 1, index_c + 1)->set(mstr); + } + } + } + m.format(printops); + result_history_text = m.print(printops).c_str(); + printops.can_display_unicode_string_arg = NULL; + /*if(result_history_text.length() > 5000) { + result_text = i18n("result is too long\nsee history"); + *printops.is_approximate = false; + } else */ + if(mm && result_text == i18n("aborted")) { + result_text = i18n("calculation was aborted"); + *printops.is_approximate = false; + } else if(mm) { + printops.allow_non_usable = true; + printops.can_display_unicode_string_arg = (void*) win->resultLabel; + QFont font(win->resultLabel->font()); + result_text = draw_structure(m, font, win->resultLabel->colorGroup(), printops); + if(result_text.find("") >= 0) { + result_text.prepend("
"); + result_text += "
"; + *do_wrap = false; + } else { + result_text.prepend("
 
"); + result_text += "
"; + *do_wrap = true; + } + printops.can_display_unicode_string_arg = NULL; + printops.allow_non_usable = false; + } + b_busy = false; + } + return NULL; +} + +void KQalculate::clearresult() { + resultLabel->setRightMargin(10); + resultLabel->setText(" "); + parsed_text = ""; + result_parts.clear(); +} + +void reduceDivLineSize(QalculateResultDisplay *resultLabel) { + + QString str = result_text; + QColorGroup cg = resultLabel->colorGroup(); + int rt_i = 0; + while(true) { + + int i2 = str.find("", 0); + if(i2 < 0) break; + str.remove(0, i2 + 48); + rt_i += i2 + 48; + i2 = str.find("
", 0); + if(i2 < 0) break; + int width_i = rt_i + i2 + 43; + QString num_str = str; + num_str.truncate(i2); + + i2 = str.find("
", i2 + 4); + if(i2 < 0) break; + str.remove(0, i2 + 11); + rt_i += i2 + 11; + i2 = str.find("", 0); + if(i2 < 0) break; + QString den_str = str; + den_str.truncate(i2); + str.remove(0, i2 + 48); + rt_i += i2 + 48; + + int den_w, num_w, w = 0, h = 0; + QSimpleRichText text_r(num_str, resultLabel->font()); text_r.setWidth(10000); + num_w = text_r.widthUsed(); + QSimpleRichText text_rn(den_str, resultLabel->font()); text_rn.setWidth(10000); + den_w = text_rn.widthUsed(); + + w = den_w; + if(num_w > w) w = num_w; + w += 2; + + QSimpleRichText textsmall("X", resultLabel->font()); + h = (int) (textsmall.height() / 1.5); + h += h % 2; + + string filename = getLocalDir(); + if(saved_divisionline_height != h) { + + QPixmap *pixmap = new QPixmap(10, h); + pixmap->fill(cg.background()); + QPainter p(pixmap); + QPen ppen = p.pen(); + ppen.setColor(cg.foreground()); + p.setPen(ppen); + p.drawLine(0, h / 2, 10, h / 2); + p.drawLine(0, h / 2 + 1, 10, h / 2 + 1); + p.flush(); + p.end(); + + pixmap->setMask(pixmap->createHeuristicMask()); + mkdir(filename.c_str(), S_IRWXU); + filename += "tmp/"; + mkdir(filename.c_str(), S_IRWXU); + filename += "divline.png"; + pixmap->save(filename.c_str(), "PNG", 100); + + delete pixmap; + + saved_divisionline_height = h; + + } else { + + filename += "tmp/divline.png"; + + } + + int height_i = result_text.find(" height=", width_i); + if(height_i < 0) break; + num_str = QString::number(w); + result_text.replace(width_i, height_i - width_i, num_str); + int i_diff = num_str.length() - (height_i - width_i); + rt_i += i_diff; + height_i += i_diff; + height_i += 8; + int height_i_end = result_text.find(" src=", height_i); + if(height_i_end < 0) break; + num_str = QString::number(h); + result_text.replace(height_i, height_i_end - height_i, num_str); + i_diff = num_str.length() - (height_i_end - height_i); + rt_i += i_diff; + + } + +} + +Prefix *set_result_prefix; +bool set_result_update_history; +bool set_result_update_parse; +bool set_result_force; +QString set_result_transformation; +size_t set_result_stack_index; +bool set_result_register_moved; + +void KQalculate::setResult(Prefix *prefix, bool update_history, bool update_parse, bool force, QString transformation, size_t stack_index, bool register_moved) { + if(expression_has_changed && !rpn_mode) { + if(!force) return; + execute_expression(); + if(!prefix) return; + } + set_result_prefix = prefix; + set_result_update_history = update_history; + set_result_update_parse = update_parse; + set_result_force = force; + set_result_transformation = transformation; + set_result_stack_index = stack_index; + set_result_register_moved = register_moved; + QTimer::singleShot(0, this, SLOT(setResult2())); +} +void KQalculate::setResult2() { + if(block_result_update) return; + Prefix *prefix = set_result_prefix; + bool update_history = set_result_update_history; + bool update_parse = set_result_update_parse; + bool force = set_result_force; + bool register_moved = set_result_register_moved; + QString transformation = set_result_transformation; + size_t stack_index = set_result_stack_index; + + if(!rpn_mode) stack_index = 0; + if(stack_index != 0) { + update_history = true; + update_parse = false; + } + if(register_moved) { + update_history = true; + update_parse = false; + } + + error_timer->stop(); + b_busy = true; + + uint history_index = 0; + int inhistory_index = 0; + if(update_history) { + if(update_parse || register_moved) { + QString text; + if(register_moved) { + text = i18n("RPN Register Moved"); + inhistory.insert(inhistory.begin(), QString::null); + inhistory_type.insert(inhistory_type.begin(), QALCULATE_HISTORY_REGISTER_MOVED); + inhistory_id.insert(inhistory_id.begin(), inhistory_current_id); + inhistory_current_id++; + inhistory_index++; + } else { + QString text2 = result_history_text; + text2.replace("&", "&"); + text2.replace(">", ">"); + text2.replace("<", "<"); + text = ""; + text += text2; + text += ""; + inhistory.insert(inhistory.begin(), text2); + inhistory_type.insert(inhistory_type.begin(), QALCULATE_HISTORY_EXPRESSION); + inhistory_id.insert(inhistory_id.begin(), inhistory_current_id); + inhistory_index++; + inhistory_current_id++; + } + int l = text.length(); + text += "

"; + text += historyBrowser->text(); + history_index = l + 1; + historyBrowser->setText(text); + } else if(initial_result_index == 0) { + b_busy = false; + error_timer->start(100); + return; + } else { + inhistory_index = initial_inhistory_index; + if(!transformation.isEmpty()) { + transformation.replace("&", "&"); + transformation.replace(">", ">"); + transformation.replace("<", "<"); + inhistory.insert(inhistory.begin(), transformation); + inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_TRANSFORMATION); + inhistory_id.insert(inhistory_id.begin() + inhistory_index, inhistory_current_id); + inhistory_current_id++; + inhistory_index++; + transformation.insert(0, ""); + transformation += ":
"; + QString text = historyBrowser->text(); + text.insert(initial_result_index, transformation); + historyBrowser->setText(text); + initial_result_index += transformation.length() - 4; + } + history_index = initial_result_index; + } + result_history_text = "?"; + } + if(update_parse) { + parsed_text = i18n("aborted"); + } + + if(stack_index == 0) { + resultLabel->setRightMargin(10); + resultLabel->setText(" "); + result_parts.clear(); + result_text = i18n("result processing was aborted"); + } + + *printops.is_approximate = false; + + printops.prefix = prefix; + + CALCULATOR->saveState(); + + bool parsed_approx = false; + bool do_wrap = true; + KQalculate *win = this; + fwrite(&win, sizeof(void*), 1, view_pipe_w); + if(stack_index == 0) { + fwrite(&mstruct, sizeof(void*), 1, view_pipe_w); + matrix_mstruct->clear(); + fwrite(&matrix_mstruct, sizeof(void*), 1, view_pipe_w); + } else { + MathStructure *mreg = CALCULATOR->getRPNRegister(stack_index + 1); + fwrite(&mreg, sizeof(void*), 1, view_pipe_w); + void *x = NULL; + fwrite(&x, sizeof(void*), 1, view_pipe_w); + } + bool *b = &do_wrap; + fwrite(&b, sizeof(bool*), 1, view_pipe_w); + if(update_parse) { + fwrite(&parsed_mstruct, sizeof(void*), 1, view_pipe_w); + bool *parsed_approx_p = &parsed_approx; + fwrite(&parsed_approx_p, sizeof(void*), 1, view_pipe_w); + fwrite(&parsed_tostruct, sizeof(void*), 1, view_pipe_w); + } else { + void *x = NULL; + fwrite(&x, sizeof(void*), 1, view_pipe_w); + } + fflush(view_pipe_w); + + struct timespec rtime; + rtime.tv_sec = 0; + rtime.tv_nsec = 20000000; + int i = 0; + while(b_busy && i < 50) { + nanosleep(&rtime, NULL); + i++; + } + i = 0; + + KProgressDialog *dialog = NULL; + if(b_busy) { + dialog = new KProgressDialog(this, "display_progress_dialog", i18n("Processing..."), i18n("Processing..."), true); + dialog->progressBar()->setPercentageVisible(false); + dialog->progressBar()->setTotalSteps(0); + dialog->showCancelButton(true); + dialog->setButtonText(i18n("Abort")); + dialog->show(); + } + if(dialog && dialog->wasCancelled()) on_abort_display(); + rtime.tv_nsec = 100000000; + while(b_busy) { + dialog->progressBar()->advance(1); + qApp->processEvents(); + nanosleep(&rtime, NULL); + if(dialog->wasCancelled()) on_abort_display(); + } + + b_busy = true; + if(dialog) { + dialog->hide(); + delete dialog; + } + + if(stack_index == 0) { + if(do_wrap) { + resultLabel->setVScrollBarMode(QScrollView::Auto); + resultLabel->setRightMargin(10); + resultLabel->setWordWrap(QTextEdit::NoWrap); + } else { + resultLabel->setVScrollBarMode(QScrollView::AlwaysOff); + resultLabel->setWordWrap(QTextEdit::NoWrap); + resultLabel->setRightMargin(0); + QString str = result_text; + str.replace("width=1 ", ""); + QSimpleRichText testrt(str, resultLabel->font()); + testrt.setWidth(resultLabel->visibleWidth() * 4); + if(testrt.widthUsed() > resultLabel->visibleWidth()) { + result_text.replace("setText(result_text); + } + + if(register_moved) { + update_parse = true; + parsed_text = result_history_text; + } + + if(update_history) { + if(result_history_text.length() > 500000) { + result_history_text = "(...)"; + } + if(parsed_text.length() > 500000) { + parsed_text = "(...)"; + } + QString new_text; + if(update_parse) { + QString str = "  "; + if(!parsed_approx) { + str += "="; + inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_PARSE); + } else { + if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) historyBrowser)) { + str += SIGN_ALMOST_EQUAL; + } else { + str += i18n("approx."); + } + inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_PARSE_APPROXIMATE); + } + str += " "; + QString str2 = parsed_text; + str2.replace("&", "&"); + str2.replace(">", ">"); + str2.replace("<", "<"); + inhistory.insert(inhistory.begin() + inhistory_index, str2); + inhistory_id.insert(inhistory_id.begin() + inhistory_index, inhistory_current_id); + inhistory_index++; + str += str2; + new_text += ""; + new_text += ""; + new_text += str; + new_text += ""; + new_text += ""; + new_text += "
"; + inhistory_current_id++; + } + if(stack_index == 0) { + display_errors(&new_text, &inhistory_index); + new_text += ""; + if(!(*printops.is_approximate) && !mstruct->isApproximate() && (update_parse || !prev_result_approx)) { + inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_RESULT); + new_text += "="; + } else { + inhistory_type.insert(inhistory_type.begin() + inhistory_index, QALCULATE_HISTORY_RESULT_APPROXIMATE); + if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) historyBrowser)) { + new_text += SIGN_ALMOST_EQUAL; + } else { + QString str_approx = "= "; + str_approx += i18n("approx."); + new_text += str_approx; + } + } + new_text += " "; + new_text += ""; + } else { + display_errors(); + } + if(rpn_mode && !register_moved) { + RPNRegisterChanged(result_history_text, stack_index); + } + if(stack_index == 0) { + QString str2 = result_history_text; + str2.replace("&", "&"); + str2.replace(">", ">"); + str2.replace("<", "<"); + new_text += ""; + new_text += ""; + new_text += str2; + new_text += " "; + new_text += ""; + inhistory.insert(inhistory.begin() + inhistory_index, str2); + inhistory_id.insert(inhistory_id.begin() + inhistory_index, inhistory_current_id); + inhistory_current_id++; + QString text = historyBrowser->text(); + initial_result_index = history_index + new_text.length() + 4; + initial_inhistory_index = inhistory_index + 1; + if(!update_parse && transformation.isEmpty()) { + new_text += "
"; + } + text.insert(history_index, new_text); + historyBrowser->setText(text); + prev_result_approx = *printops.is_approximate; + } + } + printops.prefix = NULL; + + b_busy = false; + display_errors(); + + if(!register_moved && stack_index == 0 && mstruct->isMatrix() && matrix_mstruct->isMatrix()) { + qApp->processEvents(); + expressionEdit->setFocus(); + if(update_history && update_parse && force) expressionEdit->selectAll(); + insertMatrixVector(matrix_mstruct, false, true, true); + } + error_timer->start(100); +} + +void on_abort_command() { + pthread_cancel(command_thread); + CALCULATOR->restoreState(); + CALCULATOR->clearBuffers(); + b_busy = false; + command_thread_started = false; +} + +void *command_proc(void *pipe) { + + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + FILE *command_pipe = (FILE*) pipe; + + while(true) { + + void *x = NULL; + int command_type; + fread(&command_type, sizeof(int), 1, command_pipe); + fread(&x, sizeof(void*), 1, command_pipe); + switch(command_type) { + case COMMAND_FACTORIZE: { + if(!((MathStructure*) x)->integerFactorize()) { + ((MathStructure*) x)->factorize(evalops); + } + break; + } + case COMMAND_SIMPLIFY: { + ((MathStructure*) x)->simplify(evalops); + break; + } + } + b_busy = false; + + } + return NULL; +} + +int execute_command_command_type; + +void KQalculate::executeCommand(int command_type) { + execute_command_command_type = command_type; + if(expression_has_changed && !rpn_mode) { + execute_expression(); + } + QTimer::singleShot(0, this, SLOT(executeCommand2())); +} +void KQalculate::executeCommand2() { + int command_type = execute_command_command_type; + + error_timer->stop(); + + b_busy = true; + bool command_aborted = false; + CALCULATOR->saveState(); + + if(!command_thread_started) { + pthread_create(&command_thread, &command_thread_attr, command_proc, command_pipe_r); + command_thread_started = true; + } + + fwrite(&command_type, sizeof(int), 1, command_pipe_w); + MathStructure *mfactor = new MathStructure(*mstruct); + fwrite(&mfactor, sizeof(void*), 1, command_pipe_w); + + fflush(command_pipe_w); + + struct timespec rtime; + rtime.tv_sec = 0; + rtime.tv_nsec = 20000000; + int i = 0; + while(b_busy && i < 50) { + nanosleep(&rtime, NULL); + i++; + } + i = 0; + + KProgressDialog *dialog = NULL; + if(b_busy) { + QString progress_str; + switch(command_type) { + case COMMAND_FACTORIZE: { + progress_str = i18n("Factorizing..."); + break; + } + case COMMAND_SIMPLIFY: { + progress_str = i18n("Simplifying..."); + break; + } + } + dialog = new KProgressDialog(this, "display_progress_dialog", progress_str, progress_str, true); + dialog->progressBar()->setPercentageVisible(false); + dialog->progressBar()->setTotalSteps(0); + dialog->showCancelButton(true); + dialog->setButtonText(i18n("Abort")); + dialog->show(); + } + if(dialog && dialog->wasCancelled()) { + on_abort_command(); + command_aborted = true; + } + rtime.tv_nsec = 100000000; + while(b_busy) { + dialog->progressBar()->advance(1); + qApp->processEvents(); + nanosleep(&rtime, NULL); + if(dialog->wasCancelled()) { + on_abort_command(); + command_aborted = true; + } + } + + b_busy = true; + if(dialog) { + dialog->hide(); + delete dialog; + } + + b_busy = false; + + if(!command_aborted) { + mstruct->unref(); + mstruct = mfactor; + switch(command_type) { + case COMMAND_FACTORIZE: { + printops.allow_factorization = true; + break; + } + case COMMAND_SIMPLIFY: { + printops.allow_factorization = false; + break; + } + } + set_result_prefix = NULL; + set_result_update_history = true; + set_result_update_parse = false; + set_result_force = true; + set_result_transformation = ""; + set_result_stack_index = 0; + set_result_register_moved = false; + setResult2(); + expressionEdit->setFocus(); + } + + error_timer->start(100); + +} + +void KQalculate::result_display_updated() { + setResult(NULL, false, false, false); + update_status_text(); + expressionEdit->setFocus(); +} +void KQalculate::result_format_updated() { + setResult(NULL, true, false, false); + update_status_text(); + expressionEdit->setFocus(); +} +void KQalculate::result_action_executed() { + //display_errors(); + printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE); + setResult(NULL, true, false, true); + expressionEdit->setFocus(); +} +void KQalculate::result_prefix_changed(Prefix *prefix) { + setResult(prefix, true, false, true); + expressionEdit->setFocus(); +} +void KQalculate::expression_calculation_updated() { + expression_has_changed2 = true; + displayParseStatus(); + if(!rpn_mode) execute_expression(false); + update_status_text(); + expressionEdit->setFocus(); +} +void KQalculate::expression_format_updated(bool recalculate) { + if(rpn_mode) recalculate = false; + expression_has_changed2 = true; + displayParseStatus(); + if(!expression_has_changed && !recalculate && !rpn_mode) { + clearresult(); + } + if(recalculate) { + execute_expression(false); + } + update_status_text(); + expressionEdit->setFocus(); +} + +/* + calculate entered expression and display result +*/ +size_t execute_expression_stack_index; +bool execute_expression_do_stack; +bool execute_expression_force; +bool execute_expression_do_mathoperation; +MathOperation execute_expression_op; +MathFunction *execute_expression_f; +void KQalculate::execute_expression(bool force) { + execute_expression_force = force; + execute_expression_do_stack = false; + execute_expression_do_mathoperation = false; + QTimer::singleShot(0, this, SLOT(execute_expression2())); +} +void KQalculate::execute_expression2() { + + bool force = execute_expression_force; + bool do_stack = execute_expression_do_stack; + size_t stack_index = execute_expression_stack_index; + bool do_mathoperation = execute_expression_do_mathoperation; + MathOperation op = execute_expression_op; + MathFunction *f = execute_expression_f; + + QString str; + + if(do_stack) { + str = getRPNRegister(stack_index)->text(1).stripWhiteSpace(); + error_timer->stop(); + } else { + str = expressionEdit->text().stripWhiteSpace(); + if(!force && (expression_has_changed || str.isEmpty())) return; + error_timer->stop(); + expression_has_changed = false; + if(!do_mathoperation && !str.isEmpty()) expressionEdit->addToHistory(expressionEdit->text()); + } + + size_t stack_size = 0; + + b_busy = true; + + if(!do_stack || stack_index == 0) { + parsed_text = ""; + } + if(do_stack) { + stack_size = CALCULATOR->RPNStackSize(); + CALCULATOR->setRPNRegister(stack_index + 1, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), 0, evalops, parsed_mstruct, parsed_tostruct, !printops.negative_exponents); + } else if(rpn_mode) { + stack_size = CALCULATOR->RPNStackSize(); + if(do_mathoperation) { + if(f) CALCULATOR->calculateRPN(f, 0, evalops, parsed_mstruct); + else CALCULATOR->calculateRPN(op, 0, evalops, parsed_mstruct); + } else { + string str2 = CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options); + CALCULATOR->parseSigns(str2); + if(str2.length() == 1) { + do_mathoperation = true; + switch(str2[0]) { + case '^': {CALCULATOR->calculateRPN(OPERATION_RAISE, 0, evalops, parsed_mstruct); break;} + case '+': {CALCULATOR->calculateRPN(OPERATION_ADD, 0, evalops, parsed_mstruct); break;} + case '-': {CALCULATOR->calculateRPN(OPERATION_SUBTRACT, 0, evalops, parsed_mstruct); break;} + case '*': {CALCULATOR->calculateRPN(OPERATION_MULTIPLY, 0, evalops, parsed_mstruct); break;} + case '/': {CALCULATOR->calculateRPN(OPERATION_DIVIDE, 0, evalops, parsed_mstruct); break;} + case '&': {CALCULATOR->calculateRPN(OPERATION_BITWISE_AND, 0, evalops, parsed_mstruct); break;} + case '|': {CALCULATOR->calculateRPN(OPERATION_BITWISE_OR, 0, evalops, parsed_mstruct); break;} + case '~': {CALCULATOR->calculateRPNBitwiseNot(0, evalops, parsed_mstruct); break;} + case '!': {CALCULATOR->calculateRPN(CALCULATOR->f_factorial, 0, evalops, parsed_mstruct); break;} + case '>': {CALCULATOR->calculateRPN(OPERATION_GREATER, 0, evalops, parsed_mstruct); break;} + case '<': {CALCULATOR->calculateRPN(OPERATION_LESS, 0, evalops, parsed_mstruct); break;} + case '=': {CALCULATOR->calculateRPN(OPERATION_EQUALS, 0, evalops, parsed_mstruct); break;} + default: {do_mathoperation = false;} + } + } else if(str2.length() == 2) { + if(str2 == "**") { + CALCULATOR->calculateRPN(OPERATION_RAISE, 0, evalops, parsed_mstruct); + do_mathoperation = true; + } else if(str2 == "!!") { + CALCULATOR->calculateRPN(CALCULATOR->f_factorial2, 0, evalops, parsed_mstruct); + do_mathoperation = true; + } else if(str2 == "!=" || str == "=!" || str == "<>") { + CALCULATOR->calculateRPN(OPERATION_NOT_EQUALS, 0, evalops, parsed_mstruct); + do_mathoperation = true; + } else if(str2 == "<=" || str == "=<") { + CALCULATOR->calculateRPN(OPERATION_EQUALS_LESS, 0, evalops, parsed_mstruct); + do_mathoperation = true; + } else if(str2 == ">=" || str == "=>") { + CALCULATOR->calculateRPN(OPERATION_EQUALS_GREATER, 0, evalops, parsed_mstruct); + do_mathoperation = true; + } else if(str2 == "==") { + CALCULATOR->calculateRPN(OPERATION_EQUALS, 0, evalops, parsed_mstruct); + do_mathoperation = true; + } + } + if(!do_mathoperation) { + bool had_nonnum = false, test_function = true; + int in_par = 0; + for(size_t i = 0; i < str2.length(); i++) { + if(is_in(NUMBERS, str2[i])) { + if(!had_nonnum || in_par) { + test_function = false; + break; + } + } else if(str2[i] == '(') { + if(in_par || !had_nonnum) { + test_function = false; + break; + } + in_par = i; + } else if(str2[i] == ')') { + if(i != str2.length() - 1) { + test_function = false; + break; + } + } else if(str2[i] == ' ') { + if(!in_par) { + test_function = false; + break; + } + } else if(is_in(NOT_IN_NAMES, str2[i])) { + test_function = false; + break; + } else { + if(in_par) { + test_function = false; + break; + } + had_nonnum = true; + } + } + f = NULL; + if(test_function) { + if(in_par) f = CALCULATOR->getActiveFunction(str2.substr(0, in_par)); + else f = CALCULATOR->getActiveFunction(str2); + } + if(f && f->minargs() > 1) { + KMessageBox::error(this, "Can only apply functions wich requires one argument on RPN stack."); + f = NULL; + return; + } + if(f && f->minargs() > 0) { + do_mathoperation = true; + CALCULATOR->calculateRPN(f, 0, evalops, parsed_mstruct); + } else { + CALCULATOR->RPNStackEnter(str2, 0, evalops, parsed_mstruct, parsed_tostruct, !printops.negative_exponents); + } + } + } + } else { + CALCULATOR->calculate(mstruct, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), 0, evalops, parsed_mstruct, parsed_tostruct, !printops.negative_exponents); + } + struct timespec rtime; + rtime.tv_sec = 0; + rtime.tv_nsec = 20000000; + int i = 0; + while(CALCULATOR->busy() && i < 50) { + nanosleep(&rtime, NULL); + i++; + } + i = 0; + KProgressDialog *dialog = NULL; + if(CALCULATOR->busy()) { + dialog = new KProgressDialog(this, "calculation_progress_dialog", i18n("Calculating..."), i18n("Calculating..."), true); + dialog->progressBar()->setPercentageVisible(false); + dialog->progressBar()->setTotalSteps(0); + dialog->showCancelButton(true); + dialog->setButtonText(i18n("Abort")); + dialog->show(); + } + if(dialog && dialog->wasCancelled()) CALCULATOR->abort(); + rtime.tv_nsec = 100000000; + while(CALCULATOR->busy()) { + dialog->progressBar()->advance(1); + qApp->processEvents(); + nanosleep(&rtime, NULL); + if(dialog->wasCancelled()) CALCULATOR->abort(); + } + if(dialog) { + dialog->hide(); + delete dialog; + expressionEdit->setFocus(); + } + b_busy = false; + + if(rpn_mode && (!do_stack || stack_index == 0)) { + mstruct->unref(); + mstruct = CALCULATOR->getRPNRegister(1); + if(!mstruct) mstruct = new MathStructure(); + else mstruct->ref(); + } + + //update "ans" variables + if(!do_stack || stack_index == 0) { + vans[4]->set(vans[3]->get()); + vans_id_start[4] = vans_id_start[3]; + vans_id_end[4] = vans_id_end[3]; + vans[3]->set(vans[2]->get()); + vans_id_start[3] = vans_id_start[2]; + vans_id_end[3] = vans_id_end[2]; + vans[2]->set(vans[1]->get()); + vans_id_start[2] = vans_id_start[1]; + vans_id_end[2] = vans_id_end[1]; + vans[1]->set(vans[0]->get()); + vans_id_start[1] = vans_id_start[0]; + vans_id_end[1] = inhistory_current_id - 1; + vans[0]->set(*mstruct); + vans_id_start[0] = inhistory_current_id; + vans_id_end[0] = -1; + } + + if(do_stack && stack_index > 0) { + } else if(rpn_mode && do_mathoperation) { + result_history_text = i18n("RPN Operation"); + } else { + result_history_text = str; + } + printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE); + set_result_prefix = NULL; + set_result_update_history = true; + set_result_update_parse = (!do_stack || stack_index == 0); + set_result_force = true; + set_result_transformation = ""; + set_result_register_moved = false; + if(!do_stack) set_result_stack_index = 0; + else set_result_stack_index = stack_index; + if(rpn_mode && (!do_stack || stack_index == 0)) { + expressionEdit->clear(); + if(CALCULATOR->RPNStackSize() < stack_size) { + RPNRegisterRemoved(1); + } else if(CALCULATOR->RPNStackSize() > stack_size) { + RPNRegisterAdded(""); + } + } + setResult2(); + if(!do_stack || stack_index == 0) { + expressionEdit->setFocus(); + expressionEdit->selectAll(); + } + error_timer->start(100); +} + +void KQalculate::display_errors(QString *new_text, int *inhistory_index) { + if(!CALCULATOR->message()) return; + error_timer->stop(); + bool error = false; + MessageType mtype; + QStringList strlst; + QString error_str = ""; + while(true) { + mtype = CALCULATOR->message()->type(); + if(mtype == MESSAGE_ERROR || mtype == MESSAGE_WARNING) { + QString text = CALCULATOR->message()->message().c_str(); + text.replace("&", "&"); + text.replace(">", ">"); + text.replace("<", "<"); + if(inhistory_index) { + inhistory.insert(inhistory.begin() + *inhistory_index, text); + inhistory_id.insert(inhistory_id.begin() + *inhistory_index, inhistory_current_id); + inhistory_current_id++; + if(mtype == MESSAGE_ERROR) inhistory_type.insert(inhistory_type.begin() + *inhistory_index, QALCULATE_HISTORY_ERROR); + else inhistory_type.insert(inhistory_type.begin() + *inhistory_index, QALCULATE_HISTORY_WARNING); + *inhistory_index += 1; + } + strlst.push_back(CALCULATOR->message()->message().c_str()); + if(mtype == MESSAGE_ERROR) error = true; + if(mtype == MESSAGE_ERROR) error_str += ""; + else error_str += ""; + error_str += "- "; + error_str += text; + error_str += ""; + error_str += "
"; + } else { + KMessageBox::information(this, CALCULATOR->message()->message().c_str()); + } + if(!CALCULATOR->nextMessage()) break; + } + if(!error_str.isEmpty() && new_text) { + new_text->append(error_str); + } + if(strlst.size() > 1) { + if(error) KMessageBox::error(this, strlst.join("\n"), i18n("Errors")); + else KMessageBox::error(this, strlst.join("\n"), i18n("Warnings")); + } else if(strlst.size() == 1) { + if(error) KMessageBox::error(this, strlst[0], i18n("Error")); + else KMessageBox::error(this, strlst[0], i18n("Warning")); + } + error_timer->start(100); +} + +void save_defs() { + if(!CALCULATOR->saveDefinitions()) { + KMessageBox::error(0, i18n("Couldn't write definitions")); + } +} + + +void KQalculate::create_vmenu() { + + QPopupMenu *sub, *sub3; + + menu_variables->clear(); + sub = menu_variables; + Variable *v; + tree_struct *titem, *titem2; + variable_cats.rit = variable_cats.items.rbegin(); + if(variable_cats.rit != variable_cats.items.rend()) { + titem = &*variable_cats.rit; + ++variable_cats.rit; + titem->rit = titem->items.rbegin(); + } else { + titem = NULL; + } + + menu_variables_ids.clear(); + + stack menus; + menus.push(sub); + sub3 = sub; + while(titem) { + sub = new QPopupMenu(); + QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onVariableMenuItemActivated(int))); + if(titem->item.find('&') != string::npos) { + QString str2 = titem->item.c_str(); + str2.replace("&", "&&"); + sub3->insertItem(str2, sub, -1, 0); + } else { + sub3->insertItem(titem->item.c_str(), sub, -1, 0); + } + menus.push(sub); + sub3 = sub; + for(size_t i = 0; i < titem->objects.size(); i++) { + v = (Variable*) titem->objects[i]; + if(v->isActive() && !v->isHidden()) { + if(v->title(true).find('&') != string::npos) { + QString str2 = v->title(true).c_str(); + str2.replace("&", "&&"); + menu_variables_ids[sub->insertItem(str2)] = v; + } else { + menu_variables_ids[sub->insertItem(v->title(true).c_str())] = v; + } + } + } + while(titem && titem->rit == titem->items.rend()) { + titem = titem->parent; + menus.pop(); + if(menus.size() > 0) sub3 = menus.top(); + } + if(titem) { + titem2 = &*titem->rit; + ++titem->rit; + titem = titem2; + titem->rit = titem->items.rbegin(); + } + + } + + for(size_t i = 0; i < variable_cats.objects.size(); i++) { + v = (Variable*) variable_cats.objects[i]; + if(v->isActive() && !v->isHidden()) { + menu_variables_ids[menu_variables->insertItem(v->title(true).c_str())] = v; + } + } + +} + +void KQalculate::recreate_recent_variables() { + recent_variable_ids.clear(); + bool b = false; + for(size_t i = 0; i < recent_variables.size(); i++) { + if(!CALCULATOR->stillHasVariable(recent_variables[i])) { + recent_variables.erase(recent_variables.begin() + i); + i--; + } else { + if(!b) { + menu_variables->insertSeparator(0); + b = true; + } + int id = menu_variables->insertItem(recent_variables[i]->title(true).c_str(), -1, 0); + recent_variable_ids.push_back(id); + menu_variables_ids[id] = recent_variables[i]; + } + } +} +void KQalculate::update_vmenu() { + generate_variables_tree_struct(); + create_vmenu(); + recreate_recent_variables(); + if(variables_dialog) variables_dialog->updateVariableTree(); + update_completion(); +} + +void KQalculate::create_fmenu() { + + QPopupMenu *sub, *sub3; + + menu_functions->clear(); + sub = menu_functions; + MathFunction *f; + tree_struct *titem, *titem2; + function_cats.rit = function_cats.items.rbegin(); + if(function_cats.rit != function_cats.items.rend()) { + titem = &*function_cats.rit; + ++function_cats.rit; + titem->rit = titem->items.rbegin(); + } else { + titem = NULL; + } + + menu_functions_ids.clear(); + + stack menus; + menus.push(sub); + sub3 = sub; + while(titem) { + sub = new QPopupMenu(); + QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onFunctionMenuItemActivated(int))); + if(titem->item.find('&') != string::npos) { + QString str2 = titem->item.c_str(); + str2.replace("&", "&&"); + sub3->insertItem(str2, sub, -1, 0); + } else { + sub3->insertItem(titem->item.c_str(), sub, -1, 0); + } + menus.push(sub); + sub3 = sub; + for(size_t i = 0; i < titem->objects.size(); i++) { + f = (MathFunction*) titem->objects[i]; + if(f->isActive() && !f->isHidden()) { + if(f->title(true).find('&') != string::npos) { + QString str2 = f->title(true).c_str(); + str2.replace("&", "&&"); + menu_functions_ids[sub->insertItem(str2)] = f; + } else { + menu_functions_ids[sub->insertItem(f->title(true).c_str())] = f; + } + } + } + while(titem && titem->rit == titem->items.rend()) { + titem = titem->parent; + menus.pop(); + if(menus.size() > 0) sub3 = menus.top(); + } + if(titem) { + titem2 = &*titem->rit; + ++titem->rit; + titem = titem2; + titem->rit = titem->items.rbegin(); + } + + } + + for(size_t i = 0; i < function_cats.objects.size(); i++) { + f = (MathFunction*) function_cats.objects[i]; + if(f->isActive() && !f->isHidden()) { + menu_functions_ids[menu_functions->insertItem(f->title(true).c_str())] = f; + } + } + +} +void KQalculate::recreate_recent_functions() { + recent_function_ids.clear(); + bool b = false; + for(size_t i = 0; i < recent_functions.size(); i++) { + if(!CALCULATOR->stillHasFunction(recent_functions[i])) { + recent_functions.erase(recent_functions.begin() + i); + i--; + } else { + if(!b) { + menu_functions->insertSeparator(0); + b = true; + } + int id = menu_functions->insertItem(recent_functions[i]->title(true).c_str(), -1, 0); + recent_function_ids.push_back(id); + menu_functions_ids[id] = recent_functions[i]; + } + } +} +void KQalculate::update_fmenu() { + generate_functions_tree_struct(); + create_fmenu(); + recreate_recent_functions(); + if(functions_dialog) functions_dialog->updateFunctionTree(); + if(datasets_dialog) { + datasets_dialog->updateDataSetTree(); + if(!datasets_dialog->dataSetsView->selectedItem()) datasets_dialog->dataSetSelected(); + } + update_completion(); +} + +void KQalculate::create_umenu() { + + QPopupMenu *sub, *sub3; + + menu_units->clear(); + sub = menu_units; + Unit *u; + tree_struct *titem, *titem2; + unit_cats.rit = unit_cats.items.rbegin(); + if(unit_cats.rit != unit_cats.items.rend()) { + titem = &*unit_cats.rit; + ++unit_cats.rit; + titem->rit = titem->items.rbegin(); + } else { + titem = NULL; + } + + menu_units_ids.clear(); + + stack menus; + menus.push(sub); + sub3 = sub; + while(titem) { + sub = new QPopupMenu(); + QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onUnitMenuItemActivated(int))); + if(titem->item.find('&') != string::npos) { + QString str2 = titem->item.c_str(); + str2.replace("&", "&&"); + sub3->insertItem(str2, sub, -1, 0); + } else { + sub3->insertItem(titem->item.c_str(), sub, -1, 0); + } + menus.push(sub); + sub3 = sub; + for(size_t i = 0; i < titem->objects.size(); i++) { + u = (Unit*) titem->objects[i]; + if(u->isActive() && !u->isHidden()) { + if(u->title(true).find('&') != string::npos) { + QString str2 = u->title(true).c_str(); + str2.replace("&", "&&"); + menu_units_ids[sub->insertItem(str2)] = u; + } else { + menu_units_ids[sub->insertItem(u->title(true).c_str())] = u; + } + } + } + while(titem && titem->rit == titem->items.rend()) { + titem = titem->parent; + menus.pop(); + if(menus.size() > 0) sub3 = menus.top(); + } + if(titem) { + titem2 = &*titem->rit; + ++titem->rit; + titem = titem2; + titem->rit = titem->items.rbegin(); + } + + } + + for(size_t i = 0; i < unit_cats.objects.size(); i++) { + u = (Unit*) unit_cats.objects[i]; + if(u->isActive() && !u->isHidden()) { + menu_units_ids[menu_units->insertItem(u->title(true).c_str())] = u; + } + } + + sub = new QPopupMenu(); + QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onUnitsPrefixMenuItemActivated(int))); + menu_units->insertSeparator(); + menu_units->insertItem(i18n("Prefixes"), sub); + int index = 0; + Prefix *p = CALCULATOR->getPrefix(index); + while(p) { + QString pstr; + switch(p->type()) { + case PREFIX_DECIMAL: { + QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str() << "\t(10e" << ((DecimalPrefix*) p)->exponent() << ")"; + break; + } + case PREFIX_BINARY: { + QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str() << "\t(2e" << ((BinaryPrefix*) p)->exponent() << ")"; + break; + } + case PREFIX_NUMBER: { + QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str(); + break; + } + } + menu_units_prefixes_ids[sub->insertItem(pstr)] = p; + index++; + p = CALCULATOR->getPrefix(index); + } + +} + +void KQalculate::recreate_recent_units() { + recent_unit_ids.clear(); + bool b = false; + for(size_t i = 0; i < recent_units.size(); i++) { + if(!CALCULATOR->stillHasUnit(recent_units[i])) { + recent_units.erase(recent_units.begin() + i); + i--; + } else { + if(!b) { + menu_units->insertSeparator(0); + b = true; + } + int id = menu_units->insertItem(recent_units[i]->title(true).c_str(), -1, 0); + recent_unit_ids.push_back(id); + menu_units_ids[id] = recent_units[i]; + } + } +} +void KQalculate::update_umenus() { + generate_units_tree_struct(); + create_umenu(); + recreate_recent_units(); + create_toumenu(); + if(units_dialog) units_dialog->updateUnitTree(); + if(convert_to_unit_expression_dialog) convert_to_unit_expression_dialog->updateUnitTree(); + update_completion(); +} + +void KQalculate::create_toumenu() { + + QPopupMenu *sub, *sub3; + + menu_to_unit->clear(); + sub = menu_to_unit; + Unit *u; + tree_struct *titem, *titem2; + unit_cats.rit = unit_cats.items.rbegin(); + if(unit_cats.rit != unit_cats.items.rend()) { + titem = &*unit_cats.rit; + ++unit_cats.rit; + titem->rit = titem->items.rbegin(); + } else { + titem = NULL; + } + + menu_to_unit_ids.clear(); + + stack menus; + menus.push(sub); + sub3 = sub; + while(titem) { + sub = new QPopupMenu(); + QObject::connect(sub, SIGNAL(activated(int)), this, SLOT(onConvertToUnitMenuItemActivated(int))); + if(titem->item.find('&') != string::npos) { + QString str2 = titem->item.c_str(); + str2.replace("&", "&&"); + sub3->insertItem(str2, sub, -1, 0); + } else { + sub3->insertItem(titem->item.c_str(), sub, -1, 0); + } + menus.push(sub); + sub3 = sub; + for(size_t i = 0; i < titem->objects.size(); i++) { + u = (Unit*) titem->objects[i]; + if(u->isActive() && !u->isHidden()) { + if(u->title(true).find('&') != string::npos) { + QString str2 = u->title(true).c_str(); + str2.replace("&", "&&"); + menu_to_unit_ids[sub->insertItem(str2)] = u; + } else { + menu_to_unit_ids[sub->insertItem(u->title(true).c_str())] = u; + } + } + } + while(titem && titem->rit == titem->items.rend()) { + titem = titem->parent; + menus.pop(); + if(menus.size() > 0) sub3 = menus.top(); + } + if(titem) { + titem2 = &*titem->rit; + ++titem->rit; + titem = titem2; + titem->rit = titem->items.rbegin(); + } + + } + + for(size_t i = 0; i < unit_cats.objects.size(); i++) { + u = (Unit*) unit_cats.objects[i]; + if(u->isActive() && !u->isHidden()) { + menu_to_unit_ids[menu_to_unit->insertItem(u->title(true).c_str())] = u; + } + } + +} + +void KQalculate::create_setpmenu() { + menu_set_prefix->clear(); + QObject::connect(menu_set_prefix, SIGNAL(activated(int)), this, SLOT(onSetPrefixMenuItemActivated(int))); + int index = 0; + menu_set_prefix_ids[menu_set_prefix->insertItem(i18n("No Prefix"))] = CALCULATOR->decimal_null_prefix; + Prefix *p = CALCULATOR->getPrefix(index); + while(p) { + QString pstr; + switch(p->type()) { + case PREFIX_DECIMAL: { + QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str() << "\t(10e" << ((DecimalPrefix*) p)->exponent() << ")"; + break; + } + case PREFIX_BINARY: { + QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str() << "\t(2e" << ((BinaryPrefix*) p)->exponent() << ")"; + break; + } + case PREFIX_NUMBER: { + QTextOStream(&pstr) << p->name(false, true, &can_display_unicode_string_function, (void*) menu_units).c_str(); + break; + } + } + menu_set_prefix_ids[menu_set_prefix->insertItem(pstr)] = p; + index++; + p = CALCULATOR->getPrefix(index); + } +} + + +void KQalculate::insert_text(QString name) { + expressionEdit->insert(name); + expressionEdit->setFocus(); +} +/* + insert one-argument function when button clicked +*/ +void KQalculate::insertButtonFunction(QString text, bool append_space) { + if(expressionEdit->hasSelectedText()) { + //set selection as argument + text += "("; + text += expressionEdit->selectedText(); + text += ")"; + insert_text(text); + } else { + //one-argument functions do not need parenthesis + if(append_space) { + text += " "; + } + insert_text(text); + } +} +void KQalculate::insertButtonFunction(MathFunction *f) { + const ExpressionName *ename = &f->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit); + if(f->minargs() > 1) { + QString text = ename->name.c_str(); + bool b = expressionEdit->hasSelectedText(); + text += "("; + if(b) text += expressionEdit->selectedText(); + for(int i = 1; i < f->minargs(); i++) { + text += CALCULATOR->getComma().c_str(); + text += " "; + } + text += ")"; + insert_text(text); + if(b) expressionEdit->cursorBackward(false, 1 + (f->minargs() - 2) * 2); + else expressionEdit->cursorBackward(false, 1 + (f->minargs() - 1) * 2); + } else { + if(rpn_mode && f->args() == 1) { + calculateRPN(f); + return; + } + insertButtonFunction(ename->name.c_str(), !text_length_is_one(ename->name)); + } +} + +void KQalculate::function_inserted(MathFunction *object) { + if(!object) { + return; + } + if(recent_function_ids.size() <= 0) { + menu_functions->insertSeparator(0); + } + for(size_t i = 0; i < recent_functions.size(); i++) { + if(recent_functions[i] == object) { + recent_functions.erase(recent_functions.begin() + i); + menu_functions->removeItem(recent_function_ids[i]); + recent_function_ids.erase(recent_function_ids.begin() + i); + break; + } + } + if(recent_function_ids.size() >= 5) { + recent_functions.erase(recent_functions.begin()); + menu_functions->removeItem(recent_function_ids[0]); + recent_function_ids.erase(recent_function_ids.begin()); + } + int id = menu_functions->insertItem(object->title(true).c_str(), -1, 0); + menu_functions_ids[id] = object; + recent_function_ids.push_back(id); + recent_functions.push_back(object); +} +void KQalculate::variable_inserted(Variable *object) { + if(!object) { + return; + } + if(recent_variable_ids.size() <= 0) { + menu_variables->insertSeparator(0); + } + for(size_t i = 0; i < recent_variables.size(); i++) { + if(recent_variables[i] == object) { + recent_variables.erase(recent_variables.begin() + i); + menu_variables->removeItem(recent_variable_ids[i]); + recent_variable_ids.erase(recent_variable_ids.begin() + i); + break; + } + } + if(recent_variable_ids.size() >= 5) { + recent_variables.erase(recent_variables.begin()); + menu_variables->removeItem(recent_variable_ids[0]); + recent_variable_ids.erase(recent_variable_ids.begin()); + } + int id = menu_variables->insertItem(object->title(true).c_str(), -1, 0); + menu_variables_ids[id] = object; + recent_variable_ids.push_back(id); + recent_variables.push_back(object); +} +void KQalculate::unit_inserted(Unit *object) { + if(!object) { + return; + } + if(recent_unit_ids.size() <= 0) { + menu_units->insertSeparator(0); + } + for(size_t i = 0; i < recent_units.size(); i++) { + if(recent_units[i] == object) { + recent_units.erase(recent_units.begin() + i); + menu_units->removeItem(recent_unit_ids[i]); + recent_unit_ids.erase(recent_unit_ids.begin() + i); + break; + } + } + if(recent_unit_ids.size() >= 5) { + recent_units.erase(recent_units.begin()); + menu_units->removeItem(recent_unit_ids[0]); + recent_unit_ids.erase(recent_unit_ids.begin()); + } + int id = menu_units->insertItem(object->title(true).c_str(), -1, 0); + menu_units_ids[id] = object; + recent_unit_ids.push_back(id); + recent_units.push_back(object); +} + +void KQalculate::onVariableMenuItemActivated(int id) { + if(!menu_variables_ids.contains(id)) return; + Variable *v = menu_variables_ids[id]; + if(!CALCULATOR->stillHasVariable(v)) { + KMessageBox::error(this, i18n("Variable does not exist anymore.")); + update_vmenu(); + return; + } + insert_text(v->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str()); + variable_inserted(v); +} +void KQalculate::onFunctionMenuItemActivated(int id) { + if(!menu_functions_ids.contains(id)) return; + MathFunction *f = menu_functions_ids[id]; + insertFunction(f, this); +} +void KQalculate::onUnitMenuItemActivated(int id) { + if(!menu_units_ids.contains(id)) return; + Unit *u = menu_units_ids[id]; + if(!CALCULATOR->stillHasUnit(u)) { + KMessageBox::error(this, i18n("Unit does not exist anymore.")); + update_umenus(); + return; + } + if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) { + insert_text(((CompositeUnit*) u)->print(true, printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) expressionEdit).c_str()); + } else { + insert_text(u->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, true, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str()); + } + unit_inserted(u); +} +void KQalculate::onUnitsPrefixMenuItemActivated(int id) { + if(!menu_units_prefixes_ids.contains(id)) return; + insert_text(menu_units_prefixes_ids[id]->name(printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) expressionEdit).c_str()); +} + +void KQalculate::update_completion() { + expressionEdit->updateCompletion(); + if(plot_dialog) { + plot_dialog->expressionEdit->updateCompletion(); + } +} + +void KQalculate::set_unicode_buttons() { + if(printops.use_unicode_signs) { + if(can_display_unicode_string_function(SIGN_MINUS, (void*) kpMinus)) kpMinus->setText(SIGN_MINUS); + else kpMinus->setText(MINUS); + if(can_display_unicode_string_function(SIGN_PLUS, (void*) kpPlus)) kpPlus->setText(SIGN_PLUS); + else kpPlus->setText(PLUS); + if(can_display_unicode_string_function(SIGN_MULTIPLICATION, (void*) kpTimes)) kpTimes->setText(SIGN_MULTIPLICATION); + else kpTimes->setText(MULTIPLICATION); + if(can_display_unicode_string_function(SIGN_DIVISION_SLASH, (void*) kpDivision)) kpDivision->setText(SIGN_DIVISION_SLASH); + else if(can_display_unicode_string_function(SIGN_DIVISION, (void*) kpDivision)) kpDivision->setText(SIGN_DIVISION); + else kpDivision->setText(DIVISION); + if(can_display_unicode_string_function(SIGN_SQRT, (void*) kpSqrt)) kpSqrt->setText(SIGN_SQRT); + else kpSqrt->setText("Sqrt"); + if(can_display_unicode_string_function(SIGN_MULTIDOT, (void*) kpDot)) kpDot->setText(SIGN_MULTIDOT); + else kpDot->setText(CALCULATOR->getDecimalPoint().c_str()); + } else { + kpMinus->setText(MINUS); + kpPlus->setText(PLUS); + kpTimes->setText(MULTIPLICATION); + kpDivision->setText(DIVISION); + kpSqrt->setText("Sqrt"); + kpDot->setText(CALCULATOR->getDecimalPoint().c_str()); + } +} + +void KQalculate::onExpressionChanged() { + expression_has_changed = true; + expression_has_changed2 = true; + if(!rpn_mode) clearresult(); + if(!expressionEdit->dont_change_index) expressionEdit->expression_history_index = -1; + displayParseStatus(); +} + +void KQalculate::execute() { + execute_expression_force = true; + execute_expression_do_stack = false; + execute_expression_do_mathoperation = false; + execute_expression2(); +} + +bool KQalculate::fetch_exchange_rates(int) { + KURL url(CALCULATOR->getExchangeRatesUrl().c_str()); + QString filename(CALCULATOR->getExchangeRatesFileName().c_str()); +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + if(KIO::NetAccess::download(url, filename)) { +#else + if(KIO::NetAccess::download(url, filename, this)) { +#endif + return true; + } else { + QString errorstr = i18n("Failed to download exchange rates from ECB."); + errorstr += "\n"; + errorstr += KIO::NetAccess::lastErrorString(); + KMessageBox::error(this, errorstr); + return false; + } +} + +void KQalculate::onErrorTimeout() { + if(CALCULATOR->checkSaveFunctionCalled()) { + update_vmenu(); + } + display_errors(); +} + +void KQalculate::toggleHistory(bool on) { + if(on) { + bool b = mainStack->isVisible(); + int new_height = height(); + if(bottomLine->isVisible()) new_height -= bottomLine->height(); + if(mainStack->height() > history_height) history_height = mainStack->height(); + bottomLine->hide(); + mainStack->show(); + mainStack->raiseWidget(1); + keypadButton->setOn(false); + stackButton->setOn(false); + mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false); + resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false); + if(!b) { + new_height += history_height; + resize(width(), new_height); + } else if(history_height != mainStack->height()) { + resize(width(), height() - mainStack->height() + history_height); + } + } else { + if(!keypadButton->isOn() && !stackButton->isOn()) { + history_height = mainStack->height(); + int new_height = height() - mainStack->height(); + mainStack->hide(); + bottomLine->show(); + qApp->processEvents(); + if(new_height < height()) resize(width(), new_height + bottomLine->height()); + mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false); + resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false); + } + } +} + +void KQalculate::toggleStack(bool on) { + if(on) { + bool b = mainStack->isVisible(); + int new_height = height(); + if(bottomLine->isVisible()) new_height -= bottomLine->height(); + if(mainStack->height() > history_height) history_height = mainStack->height(); + bottomLine->hide(); + mainStack->show(); + mainStack->raiseWidget(2); + keypadButton->setOn(false); + historyButton->setOn(false); + mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false); + resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false); + if(!b) { + new_height += history_height; + resize(width(), new_height); + } else if(history_height != mainStack->height()) { + resize(width(), height() - mainStack->height() + history_height); + } + } else { + if(!keypadButton->isOn() && !historyButton->isOn()) { + history_height = mainStack->height(); + int new_height = height() - mainStack->height(); + mainStack->hide(); + bottomLine->show(); + qApp->processEvents(); + if(new_height < height()) resize(width(), new_height + bottomLine->height()); + mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false); + resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false); + } + } +} + +void KQalculate::toggleKeypad(bool on) { + if(on) { + bool b = mainStack->isVisible(); + if(b) history_height = mainStack->height(); + int new_height = height() - bottomLine->height(); + mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false); + resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false); + mainStack->show(); + bottomLine->hide(); + mainStack->raiseWidget(0); + historyButton->setOn(false); + stackButton->setOn(false); + if(!b) { + qApp->processEvents(); + new_height += mainStack->height(); + resize(width(), new_height); + } else { + resize(width(), minimumSizeHint().height()); + } + } else { + if(!historyButton->isOn() && !stackButton->isOn()) { + int new_height = height() - mainStack->height(); + mainStack->hide(); + bottomLine->show(); + qApp->processEvents(); + if(new_height < height()) resize(width(), new_height + bottomLine->height()); + mainStack->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum, false); + resultLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, false); + } + } +} + +void KQalculate::showHide() { + if(isVisible()) { + hide(); + } else { +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + KWin::Info info = KWin::info(winId()); + KWin::setOnDesktop(winId(), KWin::currentDesktop()); + move(info.geometry.topLeft()); +#else + KWin::WindowInfo info = KWin::windowInfo(winId(), (unsigned long) NET::WMGeometry); + KWin::setOnDesktop(winId(), KWin::currentDesktop()); + move(info.geometry().topLeft()); +#endif + setShown(true); + show(); + raise(); +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + KWin::setActiveWindow(winId()); +#else + KWin::activateWindow(winId()); +#endif + } +} +void KQalculate::configureGlobalShortcuts() { + KKeyDialog::configure(globalAccel, 0, false); + globalAccel->writeSettings(); + globalAccel->updateConnections(); +} + +void KQalculate::abbreviateNames(bool b) { + printops.abbreviate_names = b; + result_format_updated(); +} + +void KQalculate::approximationAlwaysExact() { + kpExact->blockSignals(true); + evalops.approximation = APPROXIMATION_EXACT; + expression_calculation_updated(); + kpExact->setOn(true); + kpExact->blockSignals(false); +} +void KQalculate::approximationTryExact() { + kpExact->blockSignals(true); + evalops.approximation = APPROXIMATION_TRY_EXACT; + expression_calculation_updated(); + kpExact->setOn(false); + kpExact->blockSignals(false); +} +void KQalculate::approximationApproximate() { + kpExact->blockSignals(true); + evalops.approximation = APPROXIMATION_APPROXIMATE; + expression_calculation_updated(); + kpExact->setOn(false); + kpExact->blockSignals(false); +} + +void KQalculate::fractionalDisplayDecimal() { + kpFraction->blockSignals(true); + printops.number_fraction_format = FRACTION_DECIMAL; + result_format_updated(); + kpFraction->setOn(false); + kpFraction->blockSignals(false); +} +void KQalculate::fractionalDisplayDecimalTryExact() { + kpFraction->blockSignals(true); + printops.number_fraction_format = FRACTION_DECIMAL_EXACT; + result_format_updated(); + kpFraction->setOn(false); + kpFraction->blockSignals(false); +} +void KQalculate::fractionalDisplayFraction() { + kpFraction->blockSignals(true); + printops.number_fraction_format = FRACTION_FRACTIONAL; + result_format_updated(); + kpFraction->setOn(true); + kpFraction->blockSignals(false); +} +void KQalculate::fractionalDisplayCombined() { + kpFraction->blockSignals(true); + printops.number_fraction_format = FRACTION_COMBINED; + result_format_updated(); + kpFraction->setOn(true); + kpFraction->blockSignals(false); +} + +void KQalculate::numericalDisplayNormal() { + kpNumericCombo->blockSignals(true); + printops.min_exp = EXP_PRECISION; + result_format_updated(); + kpNumericCombo->setCurrentItem(0); + kpNumericCombo->blockSignals(false); +} +void KQalculate::numericalDisplayEngineering() { + kpNumericCombo->blockSignals(true); + printops.min_exp = EXP_BASE_3; + result_format_updated(); + kpNumericCombo->setCurrentItem(1); + kpNumericCombo->blockSignals(false); +} +void KQalculate::numericalDisplayScientific() { + kpNumericCombo->blockSignals(true); + printops.min_exp = EXP_SCIENTIFIC; + result_format_updated(); + kpNumericCombo->setCurrentItem(2); + kpNumericCombo->blockSignals(false); +} +void KQalculate::numericalDisplayPurelyScientific() { + kpNumericCombo->blockSignals(true); + printops.min_exp = EXP_PURE; + result_format_updated(); + kpNumericCombo->setCurrentItem(3); + kpNumericCombo->blockSignals(false); +} +void KQalculate::numericalDisplaySimple() { + kpNumericCombo->blockSignals(true); + printops.min_exp = EXP_NONE; + result_format_updated(); + kpNumericCombo->setCurrentItem(4); + kpNumericCombo->blockSignals(false); +} + +void KQalculate::roundHalfwayNumbersToEven(bool b) { + printops.round_halfway_to_even = b; + result_format_updated(); +} + + +void KQalculate::indicateInfiniteSeries(bool b) { + printops.indicate_infinite_series = b; + result_format_updated(); +} + +void KQalculate::sortMinusLast(bool b) { + printops.sort_options.minus_last = b; + result_format_updated(); +} + +void KQalculate::negativeExponents(bool b) { + printops.negative_exponents = b; + result_format_updated(); +} + +void KQalculate::showEndingZeroes(bool b) { + printops.show_ending_zeroes = b; + result_format_updated(); +} + +void KQalculate::updateBaseOther() { + if(set_base_dialog) { + set_base_dialog->outputBaseBox->blockSignals(true); + set_base_dialog->radiogroup_output->blockSignals(true); + set_base_dialog->outputBaseBox->setEnabled(false); + switch(printops.base) { + case BASE_BINARY: { + set_base_dialog->radiogroup_output->setButton(0); + break; + } + case BASE_OCTAL: { + set_base_dialog->radiogroup_output->setButton(1); + break; + } + case BASE_DECIMAL: { + set_base_dialog->radiogroup_output->setButton(2); + break; + } + case BASE_HEXADECIMAL: { + set_base_dialog->radiogroup_output->setButton(3); + break; + } + case BASE_SEXAGESIMAL: { + set_base_dialog->radiogroup_output->setButton(5); + break; + } + case BASE_TIME: { + set_base_dialog->radiogroup_output->setButton(6); + break; + } + case BASE_ROMAN_NUMERALS: { + set_base_dialog->radiogroup_output->setButton(7); + break; + } + default: { + set_base_dialog->radiogroup_output->setButton(4); + set_base_dialog->outputBaseBox->setEnabled(true); + set_base_dialog->outputBaseBox->setValue(printops.base); + } + } + set_base_dialog->outputBaseBox->blockSignals(false); + set_base_dialog->radiogroup_output->blockSignals(false); + } +} +void KQalculate::numberBaseBinary() { + kpBaseCombo->blockSignals(true); + printops.base = BASE_BINARY; + updateBaseOther(); + result_format_updated(); + kpBaseCombo->setCurrentItem(0); + kpBaseCombo->blockSignals(false); +} +void KQalculate::numberBaseOctal() { + kpBaseCombo->blockSignals(true); + printops.base = BASE_OCTAL; + updateBaseOther(); + result_format_updated(); + kpBaseCombo->setCurrentItem(1); + kpBaseCombo->blockSignals(false); +} +void KQalculate::numberBaseDecimal() { + kpBaseCombo->blockSignals(true); + printops.base = BASE_DECIMAL; + updateBaseOther(); + result_format_updated(); + kpBaseCombo->setCurrentItem(2); + kpBaseCombo->blockSignals(false); +} +void KQalculate::numberBaseHexadecimal() { + kpBaseCombo->blockSignals(true); + printops.base = BASE_HEXADECIMAL; + updateBaseOther(); + result_format_updated(); + kpBaseCombo->setCurrentItem(3); + kpBaseCombo->blockSignals(false); +} +void KQalculate::numberBaseSexagesimal() { + kpBaseCombo->blockSignals(true); + printops.base = BASE_SEXAGESIMAL; + updateBaseOther(); + result_format_updated(); + kpBaseCombo->setCurrentItem(4); + kpBaseCombo->blockSignals(false); +} +void KQalculate::numberBaseTimeFormat() { + kpBaseCombo->blockSignals(true); + printops.base = BASE_TIME; + updateBaseOther(); + result_format_updated(); + kpBaseCombo->setCurrentItem(5); + kpBaseCombo->blockSignals(false); +} +void KQalculate::numberBaseRomanNumerals() { + kpBaseCombo->blockSignals(true); + printops.base = BASE_ROMAN_NUMERALS; + updateBaseOther(); + result_format_updated(); + kpBaseCombo->setCurrentItem(6); + kpBaseCombo->blockSignals(false); +} +void KQalculate::numberBaseOther() { + setBase(); + set_base_dialog->radiogroup_output->setButton(4); + setBaseInResultFromDialogGroup(4); + set_base_dialog->outputBaseBox->setFocus(); + setBaseInResultFromDialogBox(set_base_dialog->outputBaseBox->value()); +} + +void KQalculate::setBaseInExpressionFromDialogBox(int value) { + evalops.parse_options.base = value; + expression_format_updated(true); +} +void KQalculate::setBaseInExpressionFromDialogGroup(int id) { + switch(id) { + case 0: { + set_base_dialog->inputBaseBox->setEnabled(false); + evalops.parse_options.base = BASE_BINARY; + break; + } + case 1: { + set_base_dialog->inputBaseBox->setEnabled(false); + evalops.parse_options.base = BASE_OCTAL; + break; + } + case 2: { + set_base_dialog->inputBaseBox->setEnabled(false); + evalops.parse_options.base = BASE_DECIMAL; + break; + } + case 3: { + set_base_dialog->inputBaseBox->setEnabled(false); + evalops.parse_options.base = BASE_HEXADECIMAL; + break; + } + case 4: { + set_base_dialog->inputBaseBox->setEnabled(true); + evalops.parse_options.base = set_base_dialog->inputBaseBox->value(); + break; + } + case 5: { + set_base_dialog->inputBaseBox->setEnabled(false); + evalops.parse_options.base = BASE_ROMAN_NUMERALS; + break; + } + } + expression_format_updated(true); +} +void KQalculate::setBaseInResultFromDialogBox(int value) { + bool b = (printops.base == value); + printops.base = value; + kpBaseCombo->blockSignals(true); + switch(value) { + case BASE_BINARY: { + ActionNumberBaseBinary->setChecked(true); + kpBaseCombo->setCurrentItem(0); + break; + } + case BASE_OCTAL: { + ActionNumberBaseOctal->setChecked(true); + kpBaseCombo->setCurrentItem(1); + break; + } + case BASE_DECIMAL: { + ActionNumberBaseDecimal->setChecked(true); + kpBaseCombo->setCurrentItem(2); + break; + } + case BASE_HEXADECIMAL: { + ActionNumberBaseHexadecimal->setChecked(true); + kpBaseCombo->setCurrentItem(3); + break; + } + default: { + ActionNumberBaseOther->setChecked(true); + kpBaseCombo->setCurrentItem(7); + break; + } + } + kpBaseCombo->blockSignals(false); + if(!b) result_format_updated(); +} +void KQalculate::setBaseInResultFromDialogGroup(int id) { + switch(id) { + case 0: { + set_base_dialog->outputBaseBox->setEnabled(false); + ActionNumberBaseBinary->activate(); + break; + } + case 1: { + set_base_dialog->outputBaseBox->setEnabled(false); + ActionNumberBaseOctal->activate(); + break; + } + case 2: { + set_base_dialog->outputBaseBox->setEnabled(false); + ActionNumberBaseDecimal->activate(); + break; + } + case 3: { + set_base_dialog->outputBaseBox->setEnabled(false); + ActionNumberBaseHexadecimal->activate(); + break; + } + case 4: { + set_base_dialog->outputBaseBox->setEnabled(true); + ActionNumberBaseOther->setChecked(true); + kpBaseCombo->blockSignals(true); + bool b = (printops.base == set_base_dialog->outputBaseBox->value()); + printops.base = set_base_dialog->outputBaseBox->value(); + kpBaseCombo->setCurrentItem(7); + kpBaseCombo->blockSignals(false); + if(!b) result_format_updated(); + break; + } + case 5: { + set_base_dialog->outputBaseBox->setEnabled(false); + ActionNumberBaseSexagesimal->activate(); + break; + } + case 6: { + set_base_dialog->outputBaseBox->setEnabled(false); + ActionNumberBaseTimeFormat->activate(); + break; + } + case 7: { + set_base_dialog->outputBaseBox->setEnabled(false); + ActionNumberBaseRomanNumerals->activate(); + break; + } + } +} +void KQalculate::setBase() { + if(!set_base_dialog) { + set_base_dialog = new QalculateSetBaseDialog(this); + QObject::connect(set_base_dialog->radiogroup_input, SIGNAL(clicked(int)), this, SLOT(setBaseInExpressionFromDialogGroup(int))); + QObject::connect(set_base_dialog->inputBaseBox, SIGNAL(valueChanged(int)), this, SLOT(setBaseInExpressionFromDialogBox(int))); + QObject::connect(set_base_dialog->radiogroup_output, SIGNAL(clicked(int)), this, SLOT(setBaseInResultFromDialogGroup(int))); + QObject::connect(set_base_dialog->outputBaseBox, SIGNAL(valueChanged(int)), this, SLOT(setBaseInResultFromDialogBox(int))); + } + set_base_dialog->inputBaseBox->blockSignals(true); + set_base_dialog->radiogroup_input->blockSignals(true); + set_base_dialog->inputBaseBox->setEnabled(false); + switch(evalops.parse_options.base) { + case BASE_BINARY: { + set_base_dialog->radiogroup_input->setButton(0); + break; + } + case BASE_OCTAL: { + set_base_dialog->radiogroup_input->setButton(1); + break; + } + case BASE_DECIMAL: { + set_base_dialog->radiogroup_input->setButton(2); + break; + } + case BASE_HEXADECIMAL: { + set_base_dialog->radiogroup_input->setButton(3); + break; + } + case BASE_ROMAN_NUMERALS: { + set_base_dialog->radiogroup_input->setButton(5); + break; + } + default: { + set_base_dialog->radiogroup_input->setButton(4); + set_base_dialog->inputBaseBox->setEnabled(true); + set_base_dialog->inputBaseBox->setValue(evalops.parse_options.base); + } + } + set_base_dialog->inputBaseBox->blockSignals(false); + set_base_dialog->radiogroup_input->blockSignals(false); + updateBaseOther(); + set_base_dialog->show(); +} + +void KQalculate::nonZeroDenominators(bool b) { + evalops.assume_denominators_nonzero = b; + expression_calculation_updated(); +} +void KQalculate::warnAboutDenominatorsAssumedNonZero(bool b) { + evalops.warn_about_denominators_assumed_nonzero = b; + if(evalops.warn_about_denominators_assumed_nonzero) expression_calculation_updated(); +} + +void KQalculate::readPrecision(bool b) { + if(b) evalops.parse_options.read_precision = READ_PRECISION_WHEN_DECIMALS; + else evalops.parse_options.read_precision = DONT_READ_PRECISION; + expression_format_updated(true); +} + +void KQalculate::limitImplicitMultiplication(bool b) { + evalops.parse_options.limit_implicit_multiplication = b; + printops.limit_implicit_multiplication = b; + expression_format_updated(true); + result_format_updated(); +} + +void KQalculate::rpnMode(bool b) { + if(b == rpn_mode) return; + rpn_mode = b; + if(rpn_mode) { + stackButton->show(); + show_history = historyButton->isOn(); + show_keypad = keypadButton->isOn(); + if(show_stack) { + stackButton->toggle(); + } + } else { + show_stack = stackButton->isOn(); + if(show_stack) { + if(show_history) historyButton->toggle(); + else if(show_keypad) keypadButton->toggle(); + else stackButton->toggle(); + } + stackButton->hide(); + CALCULATOR->clearRPNStack(); + stackList->clear(); + } + if(leftButtonsSeparator->isVisible()) { + if(rpn_mode) executeButton->setText(i18n("Enter")); + else executeButton->setText(i18n("=")); + } + if(rpn_mode) { + kpEquals->setText(i18n("Ent")); + QToolTip::add(kpEquals, i18n("Calculate expression and add to stack")); + QToolTip::add(executeButton, i18n("Calculate expression and add to stack")); + } else { + kpEquals->setText(i18n("=")); + QToolTip::add(kpEquals, i18n("Calculate expression")); + QToolTip::add(executeButton, i18n("Calculate expression")); + } +} + +void KQalculate::rpnSyntax(bool b) { + evalops.parse_options.rpn = b; + expression_format_updated(false); +} + +void KQalculate::setMinDecimals(int i) { + printops.min_decimals = i; + if(i <= 0) printops.use_min_decimals = false; + else printops.use_min_decimals = true; + result_format_updated(); +} +void KQalculate::setMaxDecimals(int i) { + printops.max_decimals = i; + if(i < 0) printops.use_max_decimals = false; + else printops.use_max_decimals = true; + result_format_updated(); +} + +void KQalculate::decimals() { + if(!decimalsDialog) { + decimalsDialog = new QalculateDecimalsDialog(this); + QObject::connect(decimalsDialog->minDecimalsBox, SIGNAL(valueChanged(int)), this, SLOT(setMinDecimals(int))); + QObject::connect(decimalsDialog->maxDecimalsBox, SIGNAL(valueChanged(int)), this, SLOT(setMaxDecimals(int))); + } + decimalsDialog->minDecimalsBox->blockSignals(true); + decimalsDialog->maxDecimalsBox->blockSignals(true); + if(printops.use_min_decimals && printops.min_decimals > 0) decimalsDialog->minDecimalsBox->setValue(printops.min_decimals); + else decimalsDialog->minDecimalsBox->setValue(0); + if(printops.use_max_decimals && printops.max_decimals >= 0) decimalsDialog->maxDecimalsBox->setValue(printops.max_decimals); + else decimalsDialog->maxDecimalsBox->setValue(-1); + decimalsDialog->minDecimalsBox->blockSignals(false); + decimalsDialog->maxDecimalsBox->blockSignals(false); + decimalsDialog->show(); +} + +void KQalculate::setPrecision(int i) { + if(i != CALCULATOR->getPrecision()) CALCULATOR->setPrecision(i); +} +void KQalculate::precision() { + if(!precisionDialog) { + precisionDialog = new QalculatePrecisionDialog(this); + QObject::connect(precisionDialog, SIGNAL(applyClicked()), this, SLOT(precisionRecalculate())); + QObject::connect(precisionDialog->precisionBox, SIGNAL(valueChanged(int)), this, SLOT(setPrecision(int))); + } + precisionDialog->precisionBox->setValue(CALCULATOR->getPrecision()); + precisionDialog->show(); +} + +void KQalculate::precisionRecalculate() { + if(precisionDialog->precisionBox->value() != CALCULATOR->getPrecision()) CALCULATOR->setPrecision(precisionDialog->precisionBox->value()); + expression_calculation_updated(); +} + +void KQalculate::assumptionTypeUnknown() { + CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_NONE); + setAssumptionsMenu(); + expression_calculation_updated(); +} +void KQalculate::assumptionTypeNonMatrix() { + CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_NONMATRIX); + setAssumptionsMenu(); + expression_calculation_updated(); +} +void KQalculate::assumptionTypeNumber() { + CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_NUMBER); + setAssumptionsMenu(); + expression_calculation_updated(); +} +void KQalculate::assumptionTypeComplex() { + CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_COMPLEX); + setAssumptionsMenu(); + expression_calculation_updated(); +} +void KQalculate::assumptionTypeReal() { + CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_REAL); + setAssumptionsMenu(); + expression_calculation_updated(); +} +void KQalculate::assumptionTypeRational() { + CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_RATIONAL); + setAssumptionsMenu(); + expression_calculation_updated(); +} +void KQalculate::assumptionTypeInteger() { + CALCULATOR->defaultAssumptions()->setType(ASSUMPTION_TYPE_INTEGER); + setAssumptionsMenu(); + expression_calculation_updated(); +} + +void KQalculate::assumptionSignUnknown() { + CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_UNKNOWN); + setAssumptionsMenu(); + expression_calculation_updated(); +} +void KQalculate::assumptionSignNonZero() { + CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_NONZERO); + setAssumptionsMenu(); + expression_calculation_updated(); +} +void KQalculate::assumptionSignPositive() { + CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_POSITIVE); + setAssumptionsMenu(); + expression_calculation_updated(); +} +void KQalculate::assumptionSignNonNegative() { + CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_NONNEGATIVE); + setAssumptionsMenu(); + expression_calculation_updated(); +} +void KQalculate::assumptionSignNegative() { + CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_NEGATIVE); + setAssumptionsMenu(); + expression_calculation_updated(); +} +void KQalculate::assumptionSignNonPositive() { + CALCULATOR->defaultAssumptions()->setSign(ASSUMPTION_SIGN_NONPOSITIVE); + setAssumptionsMenu(); + expression_calculation_updated(); +} + +void KQalculate::algebraicModeSimplify() { + evalops.structuring = STRUCTURING_SIMPLIFY; + printops.allow_factorization = false; + expression_calculation_updated(); +} +void KQalculate::algebraicModeFactorize() { + evalops.structuring = STRUCTURING_FACTORIZE; + printops.allow_factorization = true; + expression_calculation_updated(); +} +void KQalculate::algebraicModeNone() { + evalops.structuring = STRUCTURING_NONE; + printops.allow_factorization = false; + expression_calculation_updated(); +} + +void KQalculate::onModesMenuItemActivated(int id) { + loadMode(menu_modes->indexOf(id)); +} +void KQalculate::loadMode(int index) { + if(index < 0) return; + size_t i = (size_t) index; + if(i >= modes.size()) return; + printops.min_decimals = modes[i].po.min_decimals; + printops.use_min_decimals = modes[i].po.use_min_decimals; + printops.max_decimals = modes[i].po.max_decimals; + printops.use_max_decimals = modes[i].po.use_max_decimals; + CALCULATOR->setPrecision(modes[i].precision); + printops.min_exp = modes[i].po.min_exp; + printops.negative_exponents = modes[i].po.negative_exponents; + printops.sort_options.minus_last = modes[i].po.sort_options.minus_last; + printops.number_fraction_format = modes[i].po.number_fraction_format; + printops.use_unit_prefixes = modes[i].po.use_unit_prefixes; + printops.abbreviate_names = modes[i].po.abbreviate_names; + printops.use_all_prefixes = modes[i].po.use_all_prefixes; + printops.use_denominator_prefix = modes[i].po.use_denominator_prefix; + printops.place_units_separately = modes[i].po.place_units_separately; + evalops.auto_post_conversion = modes[i].eo.auto_post_conversion; + printops.base = modes[i].po.base; + evalops.parse_options.base = modes[i].eo.parse_options.base; + evalops.parse_options.read_precision = modes[i].eo.parse_options.read_precision; + evalops.assume_denominators_nonzero = modes[i].eo.assume_denominators_nonzero; + evalops.warn_about_denominators_assumed_nonzero = modes[i].eo.warn_about_denominators_assumed_nonzero; + evalops.parse_options.angle_unit = modes[i].eo.parse_options.angle_unit; + evalops.parse_options.functions_enabled = modes[i].eo.parse_options.functions_enabled; + evalops.parse_options.variables_enabled = modes[i].eo.parse_options.variables_enabled; + evalops.calculate_functions = modes[i].eo.calculate_functions; + evalops.calculate_variables = modes[i].eo.calculate_variables; + evalops.sync_units = modes[i].eo.sync_units; + evalops.parse_options.unknowns_enabled = modes[i].eo.parse_options.unknowns_enabled; + evalops.parse_options.units_enabled = modes[i].eo.parse_options.units_enabled; + evalops.allow_complex = modes[i].eo.allow_complex; + evalops.allow_infinite = modes[i].eo.allow_infinite; + evalops.structuring = modes[i].eo.structuring; + printops.indicate_infinite_series = modes[i].po.indicate_infinite_series; + printops.show_ending_zeroes = modes[i].po.show_ending_zeroes; + printops.round_halfway_to_even = modes[i].po.round_halfway_to_even; + evalops.approximation = modes[i].eo.approximation; + evalops.parse_options.rpn = modes[i].eo.parse_options.rpn; + evalops.parse_options.limit_implicit_multiplication = modes[i].eo.parse_options.limit_implicit_multiplication; + printops.limit_implicit_multiplication = modes[i].po.limit_implicit_multiplication; + printops.spacious = modes[i].po.spacious; + printops.excessive_parenthesis = modes[i].po.excessive_parenthesis; + printops.short_multiplication = modes[i].po.short_multiplication; + CALCULATOR->defaultAssumptions()->setType(modes[i].at); + CALCULATOR->defaultAssumptions()->setSign(modes[i].as); + if(modes[i].rpn_mode != rpn_mode) { + rpnMode(modes[i].rpn_mode); + } + + setModeActions(); + + if(decimalsDialog) { + decimalsDialog->minDecimalsBox->blockSignals(true); + decimalsDialog->maxDecimalsBox->blockSignals(true); + if(printops.use_min_decimals && printops.min_decimals > 0) decimalsDialog->minDecimalsBox->setValue(printops.min_decimals); + else decimalsDialog->minDecimalsBox->setValue(0); + if(printops.use_max_decimals && printops.max_decimals >= 0) decimalsDialog->maxDecimalsBox->setValue(printops.max_decimals); + else decimalsDialog->maxDecimalsBox->setValue(-1); + decimalsDialog->minDecimalsBox->blockSignals(false); + decimalsDialog->maxDecimalsBox->blockSignals(false); + } + if(precisionDialog) { + precisionDialog->precisionBox->setValue(CALCULATOR->getPrecision()); + } + updateBaseOther(); + if(set_base_dialog) { + set_base_dialog->inputBaseBox->blockSignals(true); + set_base_dialog->radiogroup_input->blockSignals(true); + set_base_dialog->inputBaseBox->setEnabled(false); + switch(evalops.parse_options.base) { + case BASE_BINARY: { + set_base_dialog->radiogroup_input->setButton(0); + break; + } + case BASE_OCTAL: { + set_base_dialog->radiogroup_input->setButton(1); + break; + } + case BASE_DECIMAL: { + set_base_dialog->radiogroup_input->setButton(2); + break; + } + case BASE_HEXADECIMAL: { + set_base_dialog->radiogroup_input->setButton(3); + break; + } + case BASE_ROMAN_NUMERALS: { + set_base_dialog->radiogroup_input->setButton(5); + break; + } + default: { + set_base_dialog->radiogroup_input->setButton(4); + set_base_dialog->inputBaseBox->setEnabled(true); + set_base_dialog->inputBaseBox->setValue(evalops.parse_options.base); + } + } + set_base_dialog->inputBaseBox->blockSignals(false); + set_base_dialog->radiogroup_input->blockSignals(false); + } + + update_status_text(); + printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE); + QString str = expressionEdit->text().stripWhiteSpace(); + if(expression_has_changed || str.isEmpty()) { + setResult(NULL, true, false, false); + } else { + execute_expression(false); + } + + expression_has_changed2 = true; + displayParseStatus(); + expressionEdit->setFocus(); +} +QalculateModeDialog::QalculateModeDialog(QWidget *parent) : KDialogBase(parent, 0, true, i18n("Save Mode"), KDialogBase::Ok | KDialogBase::Cancel, KDialogBase::Ok, true) { + setMainWidget(new QWidget(this)); + QGridLayout *grid = new QGridLayout(mainWidget(), 2, 2, 0, spacingHint()); + grid->addWidget(new QLabel(i18n("Mode name:"), mainWidget()), 0, 0); + modeCombo = new KComboBox(mainWidget()); + modeCombo->setEditable(true); + for(size_t i = 2; i < modes.size(); i++) { + modeCombo->insertItem(modes[i].name); + } + modeCombo->lineEdit()->clear(); + modeCombo->setFocus(); + modeCombo->setSizePolicy(QSizePolicy::Expanding, modeCombo->sizePolicy().verData()); + grid->addWidget(modeCombo, 0, 1); + grid->addWidget(new QLabel(i18n("Shortcut:"), mainWidget()), 1, 0); + keyButton = new KKeyButton(mainWidget()); + grid->addWidget(keyButton, 1, 1); + + connect(keyButton, SIGNAL(capturedShortcut(const KShortcut&)), this, SLOT(updateShortcut(const KShortcut&))); + connect(modeCombo, SIGNAL(activated(int)), this, SLOT(modeSelected(int))); + +} +QalculateModeDialog::~QalculateModeDialog() {} +void QalculateModeDialog::modeSelected(int index) { + index += 2; + if(index < (int) modes.size()) { + keyButton->setShortcut(modes[index].shortcut, false); + } +} +void QalculateModeDialog::updateShortcut(const KShortcut &shortcut) { + keyButton->setShortcut(shortcut, false); +} +QString QalculateModeDialog::modeName() { + return modeCombo->currentText(); +} +const KShortcut &QalculateModeDialog::modeShortcut() { + return keyButton->shortcut(); +} +void QalculateModeDialog::slotOk() { + QString name = modeName(); + if(name.isEmpty()) { + KMessageBox::error(this, i18n("Empty mode name.")); + return; + } else if(name == modes[0].name) { + KMessageBox::error(this, i18n("Preset mode cannot be overwritten.")); + return; + } + KDialogBase::slotOk(); +} +void KQalculate::saveModeAs() { + QalculateModeDialog *dialog = new QalculateModeDialog(this); + if(dialog->exec() == QDialog::Accepted) { + bool new_mode = true; + QString name = dialog->modeName().stripWhiteSpace(); + size_t index = save_mode_as(name, &new_mode); + modes[index].shortcut = dialog->modeShortcut(); + if(new_mode) { + menu_modes->insertItem(modes[index].name, -1, index); + ActionDeleteMode->setEnabled(true); + ModeObject *mo = new ModeObject(index); + mo->i_mode = index; + mode_objects.push_back(mo); + accel()->insert(QString("Load mode: ") + modes[index].name, i18n("Load meta mode: %1").arg(modes[index].name), QString::null, modes[index].shortcut, mo, SLOT(loadMode())); + } else { + accel()->setShortcut(QString("Load mode: ") + modes[index].name, modes[index].shortcut); + } + } + delete dialog; +} +void KQalculate::deleteMode() { +#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 2 + bool b_ok = false; + QStringList mode_names; + for(size_t i = 2; i < modes.size(); i++) { + mode_names += modes[i].name; + } + QString name = KInputDialog::getItem(i18n("Delete Mode"), i18n("Mode:"), mode_names, 0, false, &b_ok, this).stripWhiteSpace(); + if(b_ok) { + for(size_t i = 2; i < modes.size(); i++) { + if(modes[i].name == name) { + accel()->remove(QString("Load mode: ") + name); + modes.erase(modes.begin() + i); + delete mode_objects[i - 2]; + mode_objects.erase(mode_objects.begin() + (i - 2)); + for(QValueVector::size_type i2 = 0; i2 < mode_objects.size(); i2++) { + mode_objects[i2]->i_mode = i2 + 2; + } + menu_modes->removeItemAt(i); + if(modes.size() < 3) { + ActionDeleteMode->setEnabled(false); + } + } + } + } +#endif +} +void KQalculate::saveMode() { + save_mode(); +} + +void KQalculate::aboutToQuit() { + if(plot_dialog) plot_dialog->saveMode(); + if(save_mode_on_exit) { + save_mode(); + } else { + save_preferences(); + } + if(save_defs_on_exit) { + save_defs(); + } + pthread_cancel(view_thread); + CALCULATOR->terminateThreads(); +} + +void KQalculate::angleUnitDegrees() { + kpAngleGroup->blockSignals(true); + evalops.parse_options.angle_unit = ANGLE_UNIT_DEGREES; + expression_format_updated(true); + kpAngleGroup->setButton(0); + kpAngleGroup->blockSignals(false); +} +void KQalculate::angleUnitRadians() { + kpAngleGroup->blockSignals(true); + evalops.parse_options.angle_unit = ANGLE_UNIT_RADIANS; + expression_format_updated(true); + kpAngleGroup->setButton(1); + kpAngleGroup->blockSignals(false); +} +void KQalculate::angleUnitGradians() { + kpAngleGroup->blockSignals(true); + evalops.parse_options.angle_unit = ANGLE_UNIT_GRADIANS; + expression_format_updated(true); + kpAngleGroup->setButton(2); + kpAngleGroup->blockSignals(false); +} +void KQalculate::angleUnitNone() { + kpAngleGroup->blockSignals(true); + evalops.parse_options.angle_unit = ANGLE_UNIT_NONE; + expression_format_updated(true); + kpAngleGroup->setButton(3); + kpAngleGroup->blockSignals(false); +} + +void KQalculate::placeUnitsSeparately(bool b) { + printops.place_units_separately = b; + result_format_updated(); +} + + +void KQalculate::enableDenominatorPrefixes(bool b) { + printops.use_denominator_prefix = b; + result_format_updated(); +} + + +void KQalculate::enableUseOfAllPrefixes(bool b) { + printops.use_all_prefixes = b; + result_format_updated(); +} + + +void KQalculate::enablePrefixes(bool b) { + printops.use_unit_prefixes = b; + result_format_updated(); +} + +void KQalculate::autoNoConversion() { + evalops.auto_post_conversion = POST_CONVERSION_NONE; + expression_calculation_updated(); +} +void KQalculate::autoConvertToBaseUnits() { + evalops.auto_post_conversion = POST_CONVERSION_BASE; + expression_calculation_updated(); +} +void KQalculate::autoConvertToBestUnit() { + evalops.auto_post_conversion = POST_CONVERSION_BEST; + expression_calculation_updated(); +} + +void KQalculate::allowInfiniteResult(bool b) { + evalops.allow_infinite = b; + expression_calculation_updated(); +} + + +void KQalculate::allowComplexResult(bool b) { + evalops.allow_complex = b; + expression_calculation_updated(); +} + + +void KQalculate::calculateVariables(bool b) { + evalops.calculate_variables = b; + expression_calculation_updated(); +} + + +void KQalculate::enableUnknowns(bool b) { + evalops.parse_options.unknowns_enabled = b; + expression_format_updated(b); +} + + +void KQalculate::enableUnits(bool b) { + evalops.parse_options.units_enabled = b; + expression_format_updated(b); +} + + +void KQalculate::enableFunctions(bool b) { + evalops.parse_options.functions_enabled = b; + expression_format_updated(b); +} + + +void KQalculate::enableVariables(bool b) { + evalops.parse_options.variables_enabled = b; + expression_format_updated(b); +} + +void KQalculate::updateExchangeRates() { + if(fetch_exchange_rates(15)) { + CALCULATOR->loadExchangeRates(); + } + expression_calculation_updated(); +} + +void KQalculate::insertRaise() { + if(rpn_mode) { + calculateRPN(OPERATION_RAISE); + return; + } + if(!evalops.parse_options.rpn) { + expressionEdit->wrapSelection(); + expressionEdit->deselect(); + } + insert_text("^"); +} + + +void KQalculate::insertLn() { + insertButtonFunction(CALCULATOR->f_ln); +} + + +void KQalculate::insertLog() { + MathFunction *f = CALCULATOR->getActiveFunction("log10"); + if(f) { + insertButtonFunction(f); + } else { + KMessageBox::error(this, i18n("log10 function not found.")); + } +} + + +void KQalculate::insertSqrt() { + insertButtonFunction(CALCULATOR->f_sqrt); +} + + +void KQalculate::insertTan() { + if(kpHyp->isOn()) { + if(kpInv->isOn()) { + insertButtonFunction(CALCULATOR->f_atanh); + } else { + insertButtonFunction(CALCULATOR->f_tanh); + } + } else { + if(kpInv->isOn()) { + insertButtonFunction(CALCULATOR->f_atan); + } else { + insertButtonFunction(CALCULATOR->f_tan); + } + } +} + + +void KQalculate::insertSin() { + if(kpHyp->isOn()) { + kpHyp->setOn(false); + if(kpInv->isOn()) { + kpInv->setOn(false); + insertButtonFunction(CALCULATOR->f_asinh); + } else { + insertButtonFunction(CALCULATOR->f_sinh); + } + } else { + if(kpInv->isOn()) { + kpInv->setOn(false); + insertButtonFunction(CALCULATOR->f_asin); + } else { + insertButtonFunction(CALCULATOR->f_sin); + } + } +} + + +void KQalculate::insertCos() { + if(kpHyp->isOn()) { + kpHyp->setOn(false); + if(kpInv->isOn()) { + kpInv->setOn(false); + insertButtonFunction(CALCULATOR->f_acosh); + } else { + insertButtonFunction(CALCULATOR->f_cosh); + } + } else { + if(kpInv->isOn()) { + kpInv->setOn(false); + insertButtonFunction(CALCULATOR->f_acos); + } else { + insertButtonFunction(CALCULATOR->f_cos); + } + } +} + + +void KQalculate::insertDivision() { + if(rpn_mode) { + calculateRPN(OPERATION_DIVIDE); + return; + } + if(!evalops.parse_options.rpn) { + expressionEdit->wrapSelection(); + expressionEdit->deselect(); + } + if(printops.use_unicode_signs && printops.division_sign == DIVISION_SIGN_DIVISION && can_display_unicode_string_function(SIGN_DIVISION, (void*) expressionEdit)) { + insert_text(SIGN_DIVISION); + } else { + insert_text("/"); + } +} + + +void KQalculate::insertTimes() { + if(rpn_mode) { + calculateRPN(OPERATION_MULTIPLY); + return; + } + if(!evalops.parse_options.rpn) { + expressionEdit->wrapSelection(); + expressionEdit->deselect(); + } + if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_DOT && can_display_unicode_string_function(SIGN_MULTIDOT, (void*) expressionEdit)) { + insert_text(SIGN_MULTIDOT); + } else if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_DOT && can_display_unicode_string_function(SIGN_SMALLCIRCLE, (void*) expressionEdit)) { + insert_text(SIGN_SMALLCIRCLE); + } else if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_X && can_display_unicode_string_function(SIGN_MULTIPLICATION, (void*) expressionEdit)) { + insert_text(SIGN_MULTIPLICATION); + } else { + insert_text("*"); + } +} + + +void KQalculate::calculateRPN(int op) { + if(expression_has_changed && !expressionEdit->text().stripWhiteSpace().isEmpty()) { + execute(); + } + execute_expression_force = true; + execute_expression_do_stack = false; + execute_expression_do_mathoperation = true; + execute_expression_op = (MathOperation) op; + execute_expression_f = NULL; + execute_expression2(); +} +void KQalculate::calculateRPN(MathFunction *f) { + if(expression_has_changed && !expressionEdit->text().stripWhiteSpace().isEmpty()) { + execute(); + } + execute_expression_force = true; + execute_expression_do_stack = false; + execute_expression_do_mathoperation = true; + execute_expression_f = f; + execute_expression2(); +} +void KQalculate::RPNStackEnter(Variable *v) { + CALCULATOR->RPNStackEnter(new MathStructure(v), true); + mstruct->unref(); + mstruct = CALCULATOR->getRPNRegister(1); + mstruct->ref(); + RPNRegisterAdded(v->preferredDisplayName(printops.abbreviate_names, printops.use_unicode_signs, false, printops.use_reference_names, printops.can_display_unicode_string_function, (void*) stackList).name.c_str()); +} +void KQalculate::RPNRegisterAdded(const QString &text, size_t index) { + if(index == 0) { + new KListViewItem(stackList, QString::number(index + 1), text); + } else { + new KListViewItem(stackList, getRPNRegister(index - 1), QString::number(index + 1), text); + } + updateRPNIndexes(); + clearStackButton->setEnabled(true); +} +void KQalculate::RPNRegisterRemoved(size_t index) { + delete getRPNRegister(index); + updateRPNIndexes(); + if(CALCULATOR->RPNStackSize() == 0) { + clearStackButton->setEnabled(false); + } +} +void KQalculate::RPNRegisterChanged(const QString &text, size_t index) { + getRPNRegister(index)->setText(1, text); +} +QListViewItem *KQalculate::getRPNRegister(size_t index) { + QListViewItem *li = stackList->firstChild(); + while(li) { + if(index == 0) return li; + index--; + li = li->nextSibling(); + } + return NULL; +} +void KQalculate::clearStack() { + CALCULATOR->clearRPNStack(); + stackList->clear(); + clearresult(); + mstruct->clear(); + clearStackButton->setEnabled(false); +} +void KQalculate::registerUp() { + QListViewItem *li = stackList->selectedItem(); + if(li) { + size_t index = (size_t) li->text(0).toUInt() - 1; + if(index == 0) return; + CALCULATOR->moveRPNRegisterUp(index + 1); + QListViewItem *li2 = li->itemAbove(); + QString str = li2->text(1); + li2->setText(1, li->text(1)); + li->setText(1, str); + stackList->setSelected(li2, true); + if(index == 1) { + mstruct->unref(); + mstruct = CALCULATOR->getRPNRegister(1); + mstruct->ref(); + setResult(NULL, true, false, false, "", 0, true); + } + } +} +void KQalculate::registerDown() { + QListViewItem *li = stackList->selectedItem(); + if(li) { + size_t index = (size_t) li->text(0).toUInt() - 1; + if(index + 1 == CALCULATOR->RPNStackSize()) return; + CALCULATOR->moveRPNRegisterDown(index + 1); + QListViewItem *li2 = li->nextSibling(); + QString str = li2->text(1); + li2->setText(1, li->text(1)); + li->setText(1, str); + stackList->setSelected(li2, true); + if(index == 0) { + mstruct->unref(); + mstruct = CALCULATOR->getRPNRegister(1); + mstruct->ref(); + setResult(NULL, true, false, false, "", 0, true); + } + } +} +void KQalculate::deleteRegister() { + QListViewItem *li = stackList->selectedItem(); + if(li) { + size_t index = (size_t) li->text(0).toUInt() - 1; + CALCULATOR->deleteRPNRegister(index + 1); + delete li; + if(CALCULATOR->RPNStackSize() == 0) { + clearresult(); + mstruct->clear(); + clearStackButton->setEnabled(false); + } else if(index == 0) { + mstruct->unref(); + mstruct = CALCULATOR->getRPNRegister(1); + mstruct->ref(); + setResult(NULL, true, false, false, "", 0, true); + } + updateRPNIndexes(); + } +} +void KQalculate::editRegister() { + QListViewItem *li = stackList->selectedItem(); + if(!li) return; + stackList->rename(li, 1); +} +void KQalculate::updateRPNIndexes() { + QListViewItem *li = stackList->firstChild(); + size_t i = 1; + while(li) { + li->setText(0, QString::number(i)); + i++; + li = li->nextSibling(); + } +} +void KQalculate::stackRegisterMoved() { + QListViewItem *li = stackList->firstChild(); + size_t i = 0; + size_t old_index; + while(li) { + old_index = (size_t) li->text(0).toUInt() - 1; + if(old_index != i) { + CALCULATOR->moveRPNRegister(old_index + 1, i + 1); + if(i == 0) { + mstruct->unref(); + mstruct = CALCULATOR->getRPNRegister(1); + mstruct->ref(); + setResult(NULL, true, false, false, "", 0, true); + } + updateRPNIndexes(); + registerSelected(); + return; + } + i++; + li = li->nextSibling(); + } +} +void KQalculate::stackRegisterSet(QListViewItem *li) { + execute_expression_stack_index = (size_t) li->text(0).toUInt() - 1; + execute_expression_force = true; + execute_expression_do_stack = true; + execute_expression_do_mathoperation = false; + execute_expression2(); +} +void KQalculate::popupStackMenu(KListView*, QListViewItem *li, const QPoint &p) { + stackMenu->setItemEnabled(stackMenu->idAt(0), li != NULL); + stackMenu->setItemEnabled(stackMenu->idAt(1), li != NULL); + stackMenu->setItemEnabled(stackMenu->idAt(3), CALCULATOR->RPNStackSize() > 0); + stackMenu->popup(p); +} +void KQalculate::registerSelected() { + QListViewItem *li = stackList->selectedItem(); + if(li) { + size_t index = (size_t) li->text(0).toUInt() - 1; + registerUpButton->setEnabled(index != 0); + registerDownButton->setEnabled(index + 1 < CALCULATOR->RPNStackSize()); + editRegisterButton->setEnabled(true); + deleteRegisterButton->setEnabled(true); + } else { + registerUpButton->setEnabled(false); + registerDownButton->setEnabled(false); + editRegisterButton->setEnabled(false); + deleteRegisterButton->setEnabled(false); + } +} + +void KQalculate::insertPlus() { + if(rpn_mode) { + calculateRPN(OPERATION_ADD); + return; + } + if(!evalops.parse_options.rpn) { + expressionEdit->wrapSelection(); + expressionEdit->deselect(); + } + insert_text("+"); +} + +void KQalculate::insertMinus() { + if(rpn_mode) { + calculateRPN(OPERATION_SUBTRACT); + return; + } + if(!evalops.parse_options.rpn) { + expressionEdit->wrapSelection(); + expressionEdit->deselect(); + } + if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_MINUS, (void*) expressionEdit)) insert_text(SIGN_MINUS); + else insert_text("-"); +} + +void KQalculate::insertAns() { + insert_text(vans[0]->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str()); +} + + +void KQalculate::insertExp() { + if(rpn_mode) { + calculateRPN(OPERATION_EXP10); + return; + } + if(printops.lower_case_e) insert_text("e"); + else insert_text("E"); +} + + +void KQalculate::insertDot() { + insert_text(CALCULATOR->getDecimalPoint().c_str()); +} + + +void KQalculate::insertKP0() { + insert_text("0"); +} + + +void KQalculate::insertKP9() { + insert_text("9"); +} + + +void KQalculate::insertKP8() { + insert_text("8"); +} + + +void KQalculate::insertKP7() { + insert_text("7"); +} + + +void KQalculate::insertKP6() { + insert_text("6"); +} + + +void KQalculate::insertKP5() { + insert_text("5"); +} + + +void KQalculate::insertKP4() { + insert_text("4"); +} + + +void KQalculate::insertKP3() { + insert_text("3"); +} + + +void KQalculate::insertKP2() { + insert_text("2"); +} + + +void KQalculate::insertKP1() { + insert_text("1"); +} + +void KQalculate::expressionDel() { + expressionEdit->del(); +} + + +void KQalculate::clearExpression() { + expressionEdit->clear(); +} + +void KQalculate::insertSquare() { + if(rpn_mode) { + calculateRPN(CALCULATOR->f_sq); + return; + } + if(evalops.parse_options.rpn) { + insertButtonFunction(CALCULATOR->f_sq); + } else { + expressionEdit->wrapSelection(); + expressionEdit->deselect(); + insert_text("^2"); + } +} + +void KQalculate::setFractionMode(bool b) { + if(b) { + ActionFractionalDisplayFraction->activate(); + } else { + ActionFractionalDisplayDecimal->activate(); + } +} + +void KQalculate::setExactMode(bool b) { + if(b) { + ActionApproximationAlwaysExact->activate(); + } else { + ActionApproximationTryExact->activate(); + } +} + +void KQalculate::kpSetAngleUnit(int index) { + switch(index) { + case 0: { + ActionAngleUnitDegrees->activate(); + break; + } + case 1: { + ActionAngleUnitRadians->activate(); + break; + } + case 2: { + ActionAngleUnitGradians->activate(); + break; + } + case 3: { + ActionAngleUnitNone->activate(); + break; + } + } +} + +void KQalculate::kpSetNumericalMode(int index) { + switch(index) { + case 0: { + printops.negative_exponents = false; + printops.sort_options.minus_last = true; + ActionNumericalDisplayNormal->activate(); + break; + } + case 1: { + ActionNumericalDisplayEngineering->activate(); + break; + } + case 2: { + printops.negative_exponents = true; + printops.sort_options.minus_last = false; + ActionNumericalDisplayScientific->activate(); + break; + } + case 3: { + printops.negative_exponents = true; + printops.sort_options.minus_last = false; + ActionNumericalDisplayPurelyScientific->activate(); + break; + } + case 4: { + printops.negative_exponents = false; + printops.sort_options.minus_last = true; + ActionNumericalDisplaySimple->activate(); + break; + } + } + ActionNegativeExponents->setChecked(printops.negative_exponents); + ActionSortMinusLast->setChecked(printops.sort_options.minus_last); +} + + +void KQalculate::kpSetBaseSelected(int index) { + switch(index) { + case 7: { + numberBaseOther(); + break; + } + } +} +void KQalculate::kpSetBase(int index) { + switch(index) { + case 0: { + ActionNumberBaseBinary->activate(); + break; + } + case 1: { + ActionNumberBaseOctal->activate(); + break; + } + case 2: { + ActionNumberBaseDecimal->activate(); + break; + } + case 3: { + ActionNumberBaseHexadecimal->activate(); + break; + } + case 4: { + ActionNumberBaseSexagesimal->activate(); + break; + } + case 5: { + ActionNumberBaseTimeFormat->activate(); + break; + } + case 6: { + ActionNumberBaseRomanNumerals->activate(); + break; + } + case 7: { + ActionNumberBaseOther->activate(); + break; + } + } +} + +void KQalculate::insertMod() { + insertButtonFunction(CALCULATOR->f_mod); +} + + +void KQalculate::insertFactorial() { + if(rpn_mode) { + insertButtonFunction(CALCULATOR->f_factorial); + return; + } + expressionEdit->wrapSelection(); + expressionEdit->deselect(); + insert_text("!"); +} + +void KQalculate::storeResult() { + if(!store_dialog) { + store_dialog = new QalculateEditVariableDialog(this); + } + Variable *v = store_dialog->editVariable(i18n("Temporary"), NULL, mstruct, true); + if(v) { + update_vmenu(); + variable_inserted(v); + } +} + +void KQalculate::manageVariables() { + if(!variables_dialog) { + variables_dialog = new QalculateVariablesDialog(); + variables_dialog->updateVariableTree(); + QObject::connect(variables_dialog, SIGNAL(variablesChanged()), this, SLOT(update_vmenu())); + QObject::connect(variables_dialog, SIGNAL(insertRequest(Variable*)), this, SLOT(insertVariable(Variable*))); + } + variables_dialog->show(); +} +void KQalculate::insertVariable(Variable *v) { + insert_text(v->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str()); + variable_inserted(v); +} +void KQalculate::insertFunction(MathFunction *f, QWidget *parent) { + if(!CALCULATOR->stillHasFunction(f)) { + KMessageBox::error(parent, i18n("Function does not exist anymore.")); + update_fmenu(); + return; + } + if(f->args() == 0) { + QString str = f->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str(); + str += "()"; + insert_text(str); + function_inserted(f); + } else { + QalculateInsertFunctionDialog *dialog = new QalculateInsertFunctionDialog(f, parent, expressionEdit->selectedText()); + int rcode = dialog->exec(); + if(rcode != QDialog::Rejected) { + if(rcode == QDialog::Accepted) { + insert_text(dialog->functionExpression()); + } else { + expressionEdit->setText(dialog->functionExpression()); + execute(); + expressionEdit->setFocus(); + } + function_inserted(f); + } + delete dialog; + } +} +void KQalculate::applyFunction(MathFunction *f, QWidget *parent) { + if(!CALCULATOR->stillHasFunction(f)) { + KMessageBox::error(parent, i18n("Function does not exist anymore.")); + update_fmenu(); + return; + } + if(rpn_mode) { + calculateRPN(f); + return; + } + QString str = f->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str(); + if(f->args() == 0) { + str += "()"; + } else { + str += "("; + str += vans[0]->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str(); + str += ")"; + } + insert_text(str); + function_inserted(f); + execute(); +} + +void KQalculate::convertToUnitConvertToDialogExpression() { + error_timer->stop(); + mstruct->set(CALCULATOR->convert(*mstruct, convert_to_unit_expression_dialog->unitExpressionEdit->text().ascii(), evalops)); + result_action_executed(); + error_timer->start(100); +} + +void KQalculate::convertToUnitExpression() { + if(!convert_to_unit_expression_dialog) { + convert_to_unit_expression_dialog = new QalculateConvertUnitsDialog(this); + convert_to_unit_expression_dialog->updateUnitTree(); + QObject::connect(convert_to_unit_expression_dialog, SIGNAL(applyClicked()), this, SLOT(convertToUnitConvertToDialogExpression())); + QObject::connect(convert_to_unit_expression_dialog, SIGNAL(okClicked()), this, SLOT(convertToUnitConvertToDialogExpression())); + QObject::connect(convert_to_unit_expression_dialog, SIGNAL(unitsChanged()), this, SLOT(update_umenus())); + } + convert_to_unit_expression_dialog->show(); +} + +void KQalculate::convertNumberBases() { + if(!convert_number_bases_dialog) { + convert_number_bases_dialog = new QalculateConvertNumberBasesDialog(); + } + convert_number_bases_dialog->show(); +} + +void KQalculate::insertManagedFunction(MathFunction *f) { + insertFunction(f, functions_dialog); +} +void KQalculate::applyManagedFunction(MathFunction *f) { + applyFunction(f, functions_dialog); +} +void KQalculate::manageFunctions() { + if(!functions_dialog) { + functions_dialog = new QalculateFunctionsDialog(); + functions_dialog->updateFunctionTree(); + QObject::connect(functions_dialog, SIGNAL(functionsChanged()), this, SLOT(update_fmenu())); + QObject::connect(functions_dialog, SIGNAL(insertRequest(MathFunction*)), this, SLOT(insertManagedFunction(MathFunction*))); + QObject::connect(functions_dialog, SIGNAL(applyRequest(MathFunction*)), this, SLOT(applyManagedFunction(MathFunction*))); + } + functions_dialog->show(); +} + +void KQalculate::newUnit() { + if(!unit_edit_dialog) { + unit_edit_dialog = new QalculateEditUnitDialog(this); + } + Unit *u = unit_edit_dialog->editUnit(); + if(u) { + update_umenus(); + unit_inserted(u); + } +} + + +void KQalculate::newDataSet() { + if(!dataset_edit_dialog) { + dataset_edit_dialog = new QalculateEditDataSetDialog(this); + } + MathFunction *f = dataset_edit_dialog->editDataSet(); + if(f) { + update_fmenu(); + function_inserted(f); + } +} + + +void KQalculate::newFunction() { + if(!function_edit_dialog) { + function_edit_dialog = new QalculateEditFunctionDialog(this); + } + MathFunction *f = function_edit_dialog->editFunction(); + if(f) { + update_fmenu(); + function_inserted(f); + } +} + + +void KQalculate::newUnknownVariable() { + if(!unknown_edit_dialog) { + unknown_edit_dialog = new QalculateEditUnknownVariableDialog(this); + } + Variable *v = unknown_edit_dialog->editVariable(i18n("My Variables")); + if(v) { + update_vmenu(); + variable_inserted(v); + } +} + + +void KQalculate::newVector() { + if(!matrix_edit_dialog) { + matrix_edit_dialog = new QalculateEditMatrixVectorDialog(this); + } + Variable *v = matrix_edit_dialog->newVector(i18n("Vectors")); + if(v) { + update_vmenu(); + variable_inserted(v); + } +} + + +void KQalculate::newMatrix() { + if(!matrix_edit_dialog) { + matrix_edit_dialog = new QalculateEditMatrixVectorDialog(this); + } + Variable *v = matrix_edit_dialog->newMatrix(i18n("Matrices")); + if(v) { + update_vmenu(); + variable_inserted(v); + } +} + + +void KQalculate::newVariable() { + if(!variable_edit_dialog) { + variable_edit_dialog = new QalculateEditVariableDialog(false); + } + Variable *v = variable_edit_dialog->editVariable(i18n("My Variables")); + if(v) { + update_vmenu(); + variable_inserted(v); + } +} + + +void KQalculate::exportCSVFile() { + if(!export_csv_dialog) { + export_csv_dialog = new QalculateExportCSVDialog(this); + } + export_csv_dialog->exportCSVFile(); +} + + +void KQalculate::importCSVFile() { + if(!import_csv_dialog) { + import_csv_dialog = new QalculateImportCSVDialog(this); + } + if(import_csv_dialog->importCSVFile()) { + update_vmenu(); + } +} + + +void KQalculate::saveAsImage() { + QString filename; + while(true) { + filename = KFileDialog::getSaveFileName("qalculate.png", "image/png", this, i18n("Save Image")); + if(filename.isEmpty()) { + return; + } else { + if(QFile::exists(filename)) { + if(KMessageBox::warningContinueCancel(this, i18n("A file named \"%1\" already exists. Are you sure you want to overwrite it?" ).arg(filename), i18n("Overwrite File?"), i18n( "&Overwrite" )) != KMessageBox::Cancel) { + break; + } + } else { + break; + } + } + } + QString str = result_text; + str.replace("width=1 ", ""); + QSimpleRichText text(str, resultLabel->font()); + QPicture picture; + QPainter p(&picture); + text.setWidth(1000); + text.draw(&p, 0, 0, QRect(), QColorGroup(Qt::black, Qt::white, Qt::white, Qt::white, Qt::white, Qt::black, Qt::white)); + p.flush(); + p.end(); + QPixmap pixmap(picture.boundingRect().width(), picture.boundingRect().height()); + pixmap.fill(Qt::white); + QPainter p2(&pixmap); + p2.drawPicture(-picture.boundingRect().x(), -picture.boundingRect().y(), picture); + p2.flush(); + p2.end(); + QImage image(pixmap.convertToImage()); + image.setAlphaBuffer(true); + int h = image.height(), w = image.width(); + QRgb pixel; + for(int r =0; r < h; r++) { + for(int c =0; c < w; c++) { + pixel = image.pixel(c, r); + image.setPixel(c, r, qRgba(0, 0, 0, 0xff - ((qRed(pixel) + qBlue(pixel) + qGreen(pixel))/ 3))); + } + } + if(!image.save(filename, "PNG")) { + KMessageBox::error(this, i18n("Failed to save image.")); + } +} + + +void KQalculate::saveDefinitions() { + save_defs(); +} + + +void KQalculate::plotFunctionsData() { + if(!plot_dialog) { + plot_dialog = new QalculatePlotDialog(); + } + plot_dialog->expressionEdit->setText(expressionEdit->text()); + plot_dialog->show(); +} + + +void KQalculate::periodicTable() { + if(!periodic_table_dialog) { + periodic_table_dialog = new QalculatePeriodicTableDialog(); + } + periodic_table_dialog->show(); +} + + +void KQalculate::onSetPrefixMenuItemActivated(int id) { + if(!menu_set_prefix_ids.contains(id)) return; + result_prefix_changed(menu_set_prefix_ids[id]); +} + + +void KQalculate::onConvertToUnitMenuItemActivated(int id) { + if(!menu_to_unit_ids.contains(id)) return; + error_timer->stop(); + mstruct->set(CALCULATOR->convert(*mstruct, menu_to_unit_ids[id], evalops)); + result_action_executed(); + error_timer->start(100); +} + + + +void KQalculate::preferences() { + if(!preferences_dialog) { + preferences_dialog = new QalculatePreferencesDialog(this); + } + close_to_systray_was = close_to_systray; + display_expression_status_was = display_expression_status; + preferences_dialog->editPreferences(); +} + +void KQalculate::applyPreferences() { + if(use_custom_result_font) { + QFont font(resultLabel->font()); + font.fromString(custom_result_font); + resultLabel->setFont(font); + } else { + resultLabel->unsetFont(); + } + if(use_custom_expression_font) { + QFont font(expressionEdit->font()); + font.fromString(custom_expression_font); + expressionEdit->setFont(font); + } else { + expressionEdit->unsetFont(); + } + updateStatusLabelFonts(); + set_unicode_buttons(); + result_display_updated(); + if(close_to_systray != close_to_systray_was) { + showSystemTrayIcon(close_to_systray); + } + if(display_expression_status != display_expression_status_was) { + if(display_expression_status) { + statusLabel_l->show(); + } else { + statusLabel_l->hide(); + } + } + displayParseStatus(); + + bool use_button_pixmaps = false; + if(use_icon_buttons > 0) { + use_button_pixmaps = true; + } else if(use_icon_buttons < 0) { + KConfig config("kdeglobals", true, false); + config.setGroup("KDE"); + use_button_pixmaps = config.readBoolEntry("ShowIconsOnPushButtons", false); + } + + if(leftButtonsSeparator->isVisible() == use_button_pixmaps) { + if(use_button_pixmaps) { + leftButtonsLayout->setSpacing(3); + executeButton->setText(""); + executeButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("exec", KIcon::Small, ICON_SIZE_SMALL_MEDIUM)); + storeButton->setText(""); + storeButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("filesaveas", KIcon::Small, ICON_SIZE_SMALL_MEDIUM)); + convertButton->setText(""); + convertButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("qalculate_convert", KIcon::Small, ICON_SIZE_SMALL_MEDIUM)); + leftButtonsSeparator->hide(); + stackPageButtonsLayout->setSpacing(3); + registerUpButton->setText(""); + registerUpButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("up", KIcon::Small, ICON_SIZE_SMALL_MEDIUM)); + registerDownButton->setText(""); + registerDownButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("down", KIcon::Small, ICON_SIZE_SMALL_MEDIUM)); + editRegisterButton->setText(""); + editRegisterButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("edit", KIcon::Small, ICON_SIZE_SMALL_MEDIUM)); + deleteRegisterButton->setText(""); + deleteRegisterButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("editdelete", KIcon::Small, ICON_SIZE_SMALL_MEDIUM)); + clearStackButton->setText(""); + clearStackButton->setIconSet(KApplication::kApplication()->iconLoader()->loadIconSet("view_remove", KIcon::Small, ICON_SIZE_SMALL_MEDIUM)); + } else { + leftButtonsLayout->setSpacing(6); + if(rpn_mode) executeButton->setText(i18n("Enter")); + else executeButton->setText(i18n("=")); + executeButton->setIconSet(QIconSet()); + storeButton->setText(i18n("Store")); + storeButton->setIconSet(QIconSet()); + convertButton->setText(i18n("Convert")); + convertButton->setIconSet(QIconSet()); + leftButtonsSeparator->show(); + stackPageButtonsLayout->setSpacing(6); + registerUpButton->setText(i18n("Up")); + registerUpButton->setIconSet(QIconSet()); + registerDownButton->setText(i18n("Down")); + registerDownButton->setIconSet(QIconSet()); + editRegisterButton->setText(i18n("Edit")); + editRegisterButton->setIconSet(QIconSet()); + deleteRegisterButton->setText(i18n("Delete")); + deleteRegisterButton->setIconSet(QIconSet()); + clearStackButton->setText(i18n("Clear")); + clearStackButton->setIconSet(QIconSet()); + } + updateButtonWidths(); + } +} + + +void KQalculate::copyResult() { + QApplication::clipboard()->setText(result_history_text, QClipboard::Clipboard); +} + +void KQalculate::clearHistory() { + historyBrowser->setText(" "); + expressionEdit->setFocus(); + inhistory.clear(); + inhistory_type.clear(); + inhistory_current_id = 0; + inhistory_id.clear(); + initial_inhistory_index = 0; + initial_result_index = 0; +} + +void KQalculate::convertToBestUnit() { + error_timer->stop(); + mstruct->set(CALCULATOR->convertToBestUnit(*mstruct, evalops)); + result_action_executed(); + error_timer->start(100); +} + +void KQalculate::convertToBaseUnits() { + error_timer->stop(); + mstruct->set(CALCULATOR->convertToBaseUnits(*mstruct, evalops)); + result_action_executed(); + error_timer->start(100); +} + +void KQalculate::applySetUnknowns(bool okclicked) { + QString str; + QString result_mod = ""; + bool b = false; + mstruct->set(*mstruct_before_unknowns); + for(size_t i = 1; i <= unknowns_mstruct->size(); i++) { + str = unknowns_entries[i - 1]->text().stripWhiteSpace(); + if(unknown_changed[i - 1] || !str.isEmpty()) { + if(!result_mod.isEmpty()) { + result_mod += CALCULATOR->getComma().c_str(); + result_mod += " "; + } + result_mod += unknowns_mstruct->getChild(i)->print().c_str(); + result_mod += "="; + if(str.isEmpty()) { + result_mod += "?"; + } else { + result_mod += str; + mstruct->replace(*unknowns_mstruct->getChild(i), CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), evalops)); + b = true; + unknown_changed[i - 1] = true; + } + } + } + if(b) { + b_unknowns_changed = true; + if(okclicked && !rpn_mode) { + MathStructure mp(*mstruct); + printops.can_display_unicode_string_arg = historyBrowser; + mp.format(printops); + str = mp.print(printops).c_str(); + expressionEdit->blockSignals(true); + expressionEdit->setText(str); + printops.can_display_unicode_string_arg = NULL; + //expressionEdit->addToHistory(str); + expressionEdit->expression_history_index = -1; + expressionEdit->blockSignals(false); + expressionEdit->setFocus(); + expressionEdit->selectAll(); + expression_has_changed2 = true; + displayParseStatus(); + } + mstruct->eval(evalops); + } + if(b_unknowns_changed) { + printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE); + setResult(NULL, true, false, false, result_mod); + } + //if(!okclicked && b) mstruct->set(*mstruct_before_unknowns); +} +void KQalculate::setUnknownsApplyClicked() { + applySetUnknowns(false); +} +void KQalculate::setUnknowns() { + if(expression_has_changed && !rpn_mode) execute_expression(true); + unknowns_mstruct = new MathStructure(); + mstruct->findAllUnknowns(*unknowns_mstruct); + if(unknowns_mstruct->size() == 0) { + KMessageBox::error(this, i18n("No unknowns in result.")); + return; + } + KDialogBase *dialog = new KDialogBase(this, 0, true, i18n("Set Unknowns")); + QObject::connect(dialog, SIGNAL(applyClicked()), this, SLOT(setUnknownsApplyClicked())); + QGrid *grid = dialog->makeGridMainWidget(2, Qt::Horizontal); + unknowns_entries.clear(); + for(size_t i = 1; i <= unknowns_mstruct->size(); i++) { + new QLabel(unknowns_mstruct->getChild(i)->print().c_str(), grid); + unknowns_entries.push_back(new KLineEdit(grid)); + if(i == 1) unknowns_entries[0]->setFocus(); + } + mstruct_before_unknowns = new MathStructure(*mstruct); + b_unknowns_changed = false; + unknown_changed.clear(); + unknown_changed.resize(unknowns_mstruct->size(), false); + int response = dialog->exec(); + if(response == QDialog::Accepted) { + applySetUnknowns(true); + } else { + if(b_unknowns_changed) { + QString result_mod = ""; + for(size_t i = 1; i <= unknowns_mstruct->size(); i++) { + if(unknown_changed[i - 1]) { + if(!result_mod.isEmpty()) { + result_mod += CALCULATOR->getComma().c_str(); + result_mod += " "; + } + result_mod += unknowns_mstruct->getChild(i)->print().c_str(); + result_mod += "="; + result_mod += "?"; + } + } + mstruct->set(*mstruct_before_unknowns); + printops.allow_factorization = (evalops.structuring == STRUCTURING_FACTORIZE); + setResult(NULL, true, false, false, result_mod); + expressionEdit->setFocus(); + } + } + delete dialog; + delete mstruct_before_unknowns; + delete unknowns_mstruct; +} + + +void KQalculate::manageDataSets() { + if(!datasets_dialog) { + datasets_dialog = new QalculateDataSetsDialog(); + datasets_dialog->updateDataSetTree(); + QObject::connect(datasets_dialog, SIGNAL(dataSetsChanged()), this, SLOT(update_fmenu())); + } + datasets_dialog->show(); +} + +void KQalculate::factorize() { + executeCommand(COMMAND_FACTORIZE); +} +void KQalculate::simplify() { + executeCommand(COMMAND_SIMPLIFY); +} + +void KQalculate::manageUnits() { + if(!units_dialog) { + units_dialog = new QalculateUnitsDialog(); + units_dialog->updateUnitTree(); + QObject::connect(units_dialog, SIGNAL(unitsChanged()), this, SLOT(update_umenus())); + QObject::connect(units_dialog, SIGNAL(insertRequest(Unit*)), this, SLOT(insertUnit(Unit*))); + QObject::connect(units_dialog, SIGNAL(convertRequest(Unit*)), this, SLOT(convertResult(Unit*))); + } + units_dialog->show(); +} +void KQalculate::insertUnit(Unit *u) { + if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) { + insert_text(((CompositeUnit*) u)->print(true, printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) expressionEdit).c_str()); + } else { + insert_text(u->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, true, false, &can_display_unicode_string_function, (void*) expressionEdit).name.c_str()); + } + unit_inserted(u); +} +void KQalculate::convertResult(Unit *u) { + error_timer->stop(); + mstruct->set(CALCULATOR->convert(*mstruct, u, evalops)); + result_action_executed(); + error_timer->start(100); +} +void KQalculate::insertMatrixVector(const MathStructure *m, bool do_vector, bool is_text_struct, bool is_result) { + if(!insert_matrix_dialog) { + insert_matrix_dialog = new QalculateInsertMatrixVectorDialog(this); + } + QString str = insert_matrix_dialog->editMatrixVector(m, do_vector, is_text_struct, is_result); + if(!str.isEmpty()) { + insert_text(str); + } +} +void KQalculate::insertMatrix() { + QString str = expressionEdit->selectedText().stripWhiteSpace(); + if(!str.isEmpty()) { + MathStructure mstruct_sel; + CALCULATOR->beginTemporaryStopMessages(); + CALCULATOR->parse(&mstruct_sel, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), evalops.parse_options); + CALCULATOR->endTemporaryStopMessages(); + if(mstruct_sel.isMatrix()) { + insertMatrixVector(&mstruct_sel, false); + return; + } + } + insertMatrixVector(NULL, false); +} +void KQalculate::insertVector() { + QString str = expressionEdit->selectedText().stripWhiteSpace(); + if(!str.isEmpty()) { + MathStructure mstruct_sel; + CALCULATOR->beginTemporaryStopMessages(); + CALCULATOR->parse(&mstruct_sel, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options), evalops.parse_options); + CALCULATOR->endTemporaryStopMessages(); + if(mstruct_sel.isVector() && !mstruct_sel.isMatrix()) { + insertMatrixVector(&mstruct_sel, true); + return; + } + } + insertMatrixVector(NULL, true); +} + +void KQalculate::keyPressEvent(QKeyEvent *e) { + KMainWindow::keyPressEvent(e); + if(e->isAccepted()) return; + if(close_to_systray && e->key() == Key_Escape && e->state() == 0) { + e->accept(); + hide(); + return; + } + if(!expressionEdit->hasFocus() && e->key() != Qt::Key_Control && e->key() != Qt::Key_Meta && e->key() != Qt::Key_Shift && e->key() != Qt::Key_Alt) { + expressionEdit->setFocus(); + expressionEdit->keyPressEvent(e); + } +} + +bool KQalculate::queryClose() { + if(m_parent->sessionSaving() || !close_to_systray) return true; + hide(); + setShown(false); + return false; +} +void KQalculate::saveProperties(KConfig*) { + KConfig *cfg = KGlobal::config(); + cfg->setGroup("Session"); + cfg->writeEntry("docked", isHidden()); +} +void KQalculate::readProperties(KConfig*) { + KConfig *cfg = KGlobal::config(); + cfg->setGroup("Session"); + if(close_to_systray && cfg->readBoolEntry("docked", true)) { + hide(); + } else { + show(); + } +} + +void KQalculate::display_function_hint(MathFunction *f, int arg_index) { + if(!f) return; + int iargs = f->maxargs(); + Argument *arg; + Argument default_arg; + QString str, str2, str3; + const ExpressionName *ename = &f->preferredName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) statusLabel_l); + bool last_is_vctr = f->getArgumentDefinition(iargs) && f->getArgumentDefinition(iargs)->type() == ARGUMENT_TYPE_VECTOR; + if(arg_index > iargs && iargs >= 0 && !last_is_vctr) { + statusLabel_l->setText(i18n("Too many arguments for %1().").arg(ename->name.c_str()), false, false, true); + return; + } + str += ename->name.c_str(); + if(iargs < 0) { + iargs = f->minargs() + 1; + if(arg_index > iargs) arg_index = iargs; + } + if(arg_index > iargs && last_is_vctr) arg_index = iargs; + + str += "("; + int i_reduced = 0; + if(iargs != 0) { + for(int i2 = 1; i2 <= iargs; i2++) { + if(i2 > f->minargs() && arg_index < i2) { + str += "["; + } + if(i2 > 1) { + str += CALCULATOR->getComma().c_str(); + str += " "; + } + if(i2 == arg_index) str += ""; + arg = f->getArgumentDefinition(i2); + if(arg && !arg->name().empty()) { + str2 = arg->name().c_str(); + } else { + str2 = i18n("argument"); + str2 += " "; + str2 += QString::number(i2); + } + if(i2 == arg_index) { + if(arg) { + if(i_reduced == 2) str3 = arg->print().c_str(); + else str3 = arg->printlong().c_str(); + } else { + Argument arg_default; + if(i_reduced == 2) str3 = arg_default.print().c_str(); + else str3 = arg_default.printlong().c_str(); + } + if(!str3.isEmpty()) { + str2 += ": "; + str2 += str3; + } + str2.replace("&", "&"); + str2.replace(">", ">"); + str2.replace("<", "<"); + str += str2; + str += ""; + if(i_reduced < 2) { + QSimpleRichText qsrt(str, statusLabel_l->font()); + qsrt.setWidth(statusLabel_l->contentsRect().width() + 100); + if(qsrt.widthUsed() > statusLabel_l->contentsRect().width() - 4) { + str = ename->name.c_str(); + str += "("; + if(i2 != 1) { + str += "..."; + i_reduced++; + } else { + i_reduced = 2; + } + i2--; + } + } else { + i_reduced = 0; + } + } else { + str2.replace("&", "&"); + str2.replace(">", ">"); + str2.replace("<", "<"); + str += str2; + if(i2 > f->minargs() && arg_index < i2) { + str += "]"; + } + } + } + if(f->maxargs() < 0) { + str += CALCULATOR->getComma().c_str(); + str += " ..."; + } + } + str += ")"; + statusLabel_l->setText(str, false, false, false); +} + +void KQalculate::displayParseStatus() { + if(!display_expression_status) return; + if(expressionEdit->text().length() == 0) { + statusLabel_l->setText("", true, false, false); + parsed_expression = ""; + expression_has_changed2 = false; + had_errors_before = false; + had_warnings_before = false; + return; + } + MathStructure mparse, mfunc; + string str_e, str_u; + int pos = expressionEdit->cursorPosition(); + bool full_parsed = false; + bool had_errors = false, had_warnings = false; + evalops.parse_options.preserve_format = true; + if(pos > 0) { + evalops.parse_options.unended_function = &mfunc; + CALCULATOR->beginTemporaryStopMessages(); + if(pos < (int) expressionEdit->text().length()) { + QString str = expressionEdit->text(); + str.truncate(pos); + str_e = CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options); + if(!CALCULATOR->separateToExpression(str_e, str_u, evalops)) { + CALCULATOR->parse(&mparse, str_e, evalops.parse_options); + } + } else { + str_e = CALCULATOR->unlocalizeExpression(expressionEdit->text().ascii(), evalops.parse_options); + CALCULATOR->separateToExpression(str_e, str_u, evalops); + CALCULATOR->parse(&mparse, str_e, evalops.parse_options); + full_parsed = true; + } + int warnings_count; + had_errors = CALCULATOR->endTemporaryStopMessages(NULL, &warnings_count) > 0; + had_warnings = warnings_count > 0; + evalops.parse_options.unended_function = NULL; + } + if(mfunc.isFunction()) { + if(mfunc.countChildren() == 0) { + display_function_hint(mfunc.function(), 1); + } else { + display_function_hint(mfunc.function(), mfunc.countChildren()); + } + } + if(expression_has_changed2) { + if(!full_parsed) { + CALCULATOR->beginTemporaryStopMessages(); + str_e = CALCULATOR->unlocalizeExpression(expressionEdit->text().ascii(), evalops.parse_options); + CALCULATOR->separateToExpression(str_e, str_u, evalops); + CALCULATOR->parse(&mparse, str_e, evalops.parse_options); + int warnings_count; + had_errors = CALCULATOR->endTemporaryStopMessages(NULL, &warnings_count) > 0; + had_warnings = warnings_count > 0; + } + PrintOptions po; + po.preserve_format = true; + po.show_ending_zeroes = true; + po.lower_case_e = printops.lower_case_e; + po.lower_case_numbers = printops.lower_case_numbers; + po.base_display = printops.base_display; + po.abbreviate_names = false; + po.hide_underscore_spaces = true; + po.use_unicode_signs = printops.use_unicode_signs; + po.multiplication_sign = printops.multiplication_sign; + po.division_sign = printops.division_sign; + po.short_multiplication = false; + po.excessive_parenthesis = true; + po.improve_division_multipliers = false; + po.can_display_unicode_string_function = &can_display_unicode_string_function; + po.can_display_unicode_string_arg = (void*) statusLabel_l; + po.spell_out_logical_operators = printops.spell_out_logical_operators; + po.restrict_to_parent_precision = false; + mparse.format(po); + parsed_expression = mparse.print(po).c_str(); + if(!str_u.empty()) { + parsed_expression += CALCULATOR->localToString().c_str(); + CALCULATOR->beginTemporaryStopMessages(); + CompositeUnit cu("", "temporary_composite_parse", "", str_u); + int warnings_count; + had_errors = CALCULATOR->endTemporaryStopMessages(NULL, &warnings_count) > 0 || had_errors; + had_warnings = had_warnings || warnings_count > 0; + mparse = cu.generateMathStructure(!printops.negative_exponents); + mparse.format(po); + parsed_expression += mparse.print(po).c_str(); + } + parsed_expression.replace("&", "&"); + parsed_expression.replace(">", ">"); + parsed_expression.replace("<", "<"); + if(!mfunc.isFunction()) statusLabel_l->setText(parsed_expression, true, had_errors, had_warnings); + expression_has_changed2 = false; + had_errors_before = had_errors; + had_warnings_before = had_warnings; + } else if(!mfunc.isFunction()) { + statusLabel_l->setText(parsed_expression, true, had_errors_before, had_warnings_before); + } + evalops.parse_options.preserve_format = false; +} + +void KQalculate::editHistoryExpression() { + if(current_history_index < inhistory.size()) { + QString text = inhistory[current_history_index]; + text.replace("&", "&"); + text.replace(">", ">"); + text.replace("<", "<"); + text.replace("
", " "); + expressionEdit->setText(text); + expressionEdit->setFocus(); + } +} +void KQalculate::editHistoryParse() { + if(current_history_index < inhistory.size()) { + QString text = inhistory[current_history_index]; + text.replace("&", "&"); + text.replace(">", ">"); + text.replace("<", "<"); + text.replace("
", " "); + expressionEdit->setText(text); + expressionEdit->setFocus(); + } +} +void KQalculate::editHistoryResult() { + if(current_history_index < inhistory.size()) { + QString text = inhistory[current_history_index]; + text.replace("&", "&"); + text.replace(">", ">"); + text.replace("<", "<"); + text.replace("
", " "); + expressionEdit->setText(text); + expressionEdit->setFocus(); + } +} +void KQalculate::insertHistoryResultVariable() { + if(current_history_index < inhistory.size()) { + int id = inhistory_id[current_history_index]; + for(size_t i = 0; i < 5; i++) { + if(vans_id_start[i] != -1 && id >= vans_id_start[i] && (vans_id_end[i] == -1 || id <= vans_id_end[i])) { + insertVariable(vans[i]); + } + } + } +} + +QalculateHistoryBrowser::QalculateHistoryBrowser(QWidget *parent, const char *name) : KTextBrowser(parent, name) {} +QalculateHistoryBrowser::~QalculateHistoryBrowser() {} + +QPopupMenu *QalculateHistoryBrowser::createPopupMenu(const QPoint &pos) { + + QPopupMenu *menu = KTextBrowser::createPopupMenu(pos); + menu->insertSeparator(); + mainWin->ActionClearHistory->plug(menu); + QString name = anchorAt(pos, Qt::AnchorName); + if(!name.isEmpty()) { + int id = name.toInt(); + QValueVector::size_type i = 0; + for(; i < inhistory_id.size(); i++) { + if(inhistory_id[i] == id) { + break; + } + } + mainWin->current_history_index = i; + if(i < inhistory_id.size()) { + switch(inhistory_type[i]) { + case QALCULATE_HISTORY_PARSE: {} + case QALCULATE_HISTORY_PARSE_APPROXIMATE: { + menu->insertItem(i18n("Edit Expression"), mainWin, SLOT(editHistoryParse())); + break; + } + case QALCULATE_HISTORY_EXPRESSION: { + menu->insertItem(i18n("Edit Expression"), mainWin, SLOT(editHistoryExpression())); + break; + } + case QALCULATE_HISTORY_RESULT_APPROXIMATE: {} + case QALCULATE_HISTORY_RESULT: { + menu->insertItem(i18n("Edit Result"), mainWin, SLOT(editHistoryResult())); + for(size_t i = 0; i < 5; i++) { + if(vans_id_start[i] != -1 && id >= vans_id_start[i] && (vans_id_end[i] == -1 || id <= vans_id_end[i])) { + menu->insertItem(i18n("Insert Result Variable"), mainWin, SLOT(insertHistoryResultVariable())); + break; + } + } + break; + } + default: {} + } + } + } + return menu; + +} + + +QalculateParseLabel::QalculateParseLabel(QWidget *parent, const char *name) : QLabel(parent, name) { + QLabel::setText("A"); + bb = false; + ec = false; + wc = false; +} +QalculateParseLabel::~QalculateParseLabel() {} +void QalculateParseLabel::setText(QString text, bool break_begin, bool error_color, bool warning_color) { + bb = break_begin; + ec = error_color; + wc = warning_color; + parsetext = ""; + parsetext += text; + parsetext += ""; + update(); +} +void QalculateParseLabel::drawContents(QPainter *p) { + QColorGroup cg = colorGroup(); + if(ec) { + cg.setColor(QColorGroup::Text, status_error_color); + } else if(wc) { + cg.setColor(QColorGroup::Text, status_warning_color); + } else if(backgroundMode() != PaletteBase && isEnabled()) { + cg.setColor(QColorGroup::Text, paletteForegroundColor()); + } + + QRect cr = contentsRect(); + cr.setX(cr.x() + 4); + cr.setWidth(cr.width() - 4); + QSimpleRichText qsrt(parsetext, font()); + qsrt.setWidth(p, cr.width() + 100); + if(qsrt.widthUsed() > cr.width()) { + if(bb) { + QSimpleRichText qsrt_dots("...", font()); + qsrt_dots.draw(p, cr.x(), cr.y(), cr, cg, 0); + cr.setX(cr.x() + qsrt_dots.widthUsed()); + cr.setWidth(cr.width() - qsrt_dots.widthUsed()); + qsrt.draw(p, cr.x() + cr.width() - qsrt.widthUsed(), cr.y(), cr, cg, 0); + } else { + QSimpleRichText qsrt_dots("...", font()); + qsrt_dots.draw(p, cr.x() + cr.width() - qsrt_dots.widthUsed(), cr.y(), cr, cg, 0); + cr.setWidth(cr.width() - qsrt_dots.widthUsed()); + qsrt.draw(p, cr.x(), cr.y(), cr, cg, 0); + } + } else { + qsrt.draw(p, cr.x(), cr.y(), cr, cg, 0); + } +} + +QalculateButton::QalculateButton(QWidget *parent, const char *name) : QPushButton(parent, name) { + setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); + umtcw = true; +#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4 + KAcceleratorManager::setNoAccel(this); +#endif + +} +QalculateButton::QalculateButton(const QString &text, QWidget *parent, const char *name) : QPushButton(text, parent, name) { + setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); + umtcw = true; +#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4 + KAcceleratorManager::setNoAccel(this); +#endif +} +QalculateButton::QalculateButton(const QIconSet &icon, const QString &text, QWidget *parent, const char *name) : QPushButton(icon, text, parent, name) { + setSizePolicy(QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum)); + umtcw = true; +#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR >= 4 + KAcceleratorManager::setNoAccel(this); +#endif +} +QalculateButton::~QalculateButton() {} + +void QalculateButton::setUseMinThreeCharWidth(bool b) { + umtcw = b; +} +void QalculateButton::setMarkup(const QString &str) { + QColorGroup cg(colorGroup()); + cg.setColor(QColorGroup::Text, paletteForegroundColor()); + QSimpleRichText rtext(str, font()); + QPicture picture; + QPainter p(&picture); + rtext.draw(&p, 0, 0, QRect(), cg); + p.flush(); + p.end(); + QRect r = picture.boundingRect(); + QPixmap pixmap(r.width(), rtext.height()); + pixmap.fill(cg.background()); + QPainter p2(&pixmap); + p2.drawPicture(-r.x(), 0, picture); + p2.flush(); + p2.end(); + pixmap.setMask(pixmap.createHeuristicMask()); + setPixmap(pixmap); +} + +QSize QalculateButton::sizeHint() const { + + constPolish(); + + int w = 0, h = 0; + + +#ifndef QT_NO_ICONSET + if(iconSet() && !iconSet()->isNull()) { + w = iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).width() + 10; + h = iconSet()->pixmap( QIconSet::Small, QIconSet::Normal ).height() + 10; + return QSize(w, h).expandedTo(QApplication::globalStrut()); + } +#endif + + QSize sz; + + if(pixmap()) { + QPixmap *pm = (QPixmap *)pixmap(); + w = pm->width(); + h = pm->height(); + if(umtcw) { + QFontMetrics fm = fontMetrics(); + sz = fm.size(ShowPrefix, QString::fromLatin1("XXX")); + if(w < sz.width()) w = sz.width(); + if(w < sz.height()) w = sz.height(); + } + sz.setWidth(w); + sz.setHeight(h); + w += 12; + h += 10; + } else { + QFontMetrics fm = fontMetrics(); + if(umtcw && (text().isEmpty() || text().length() < 3)) { + sz = fm.size(ShowPrefix, QString::fromLatin1("XXX")); + } else { + sz = fm.size(ShowPrefix, text()); + } + w = sz.width() + 12; + h = sz.height() + 10; + } + + return QSize(w, h).boundedTo(style().sizeFromContents(QStyle::CT_PushButton, this, sz)).expandedTo(QApplication::globalStrut()); + +} + +QalculateStyleSheet::QalculateStyleSheet(QObject *parent, const char *name) : QStyleSheet(parent, name) {} +QalculateStyleSheet::~QalculateStyleSheet() {} + +void QalculateStyleSheet::scaleFont(QFont &font, int logicalSize) const { + + if(logicalSize <= 1) { + font.setPixelSize(1); + } else if(logicalSize == 2) { + logicalSize = 1; + } else if(logicalSize > 7) { + logicalSize = 7; + } + + int baseSize = font.pointSize(); + + bool pixel = FALSE; + if(baseSize == -1){ + baseSize = font.pixelSize(); + pixel = TRUE; + } + + float factor = baseSize; + int i; + int scale_level = logicalSize - 3; + + if(scale_level > 0) { + i = 0; + while (i < scale_level) { + factor *= 1.2; + ++i; + } + } else if(scale_level < 0) { + i = scale_level; + while (i < 0) { + factor /= 1.2; + ++i; + } + } + + if(pixel) font.setPixelSize((int) roundf(factor)); + else font.setPointSizeFloat(factor); + +} + +QalculateRPNStackListView::QalculateRPNStackListView(QWidget *parent, const char *name) : KListView(parent, name) {} +QalculateRPNStackListView::~QalculateRPNStackListView() {} + +void QalculateRPNStackListView::keyPressEvent(QKeyEvent *e) { + switch(e->key()) { + case Key_Prior: {} + case Key_Next: {} + case Key_Home: {} + case Key_End: {} + case Key_Up: {} + case Key_Down: { + KListView::keyPressEvent(e); + break; + } + default: { + if(e->key() == KGlobalSettings::contextMenuKey()) KListView::keyPressEvent(e); + else e->ignore(); + } + } +} + +#include "kqalculate.moc" diff --git a/src/kqalculate.h b/src/kqalculate.h new file mode 100644 index 0000000..fb016e0 --- /dev/null +++ b/src/kqalculate.h @@ -0,0 +1,593 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef KQALCULATE_H +#define KQALCULATE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 menu_variables_ids; + QMap menu_functions_ids; + QMap menu_units_ids, menu_to_unit_ids; + QMap menu_units_prefixes_ids, menu_set_prefix_ids; + QValueVector recent_function_ids; + QValueVector recent_variable_ids; + QValueVector 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::size_type current_history_index; + QValueVector 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 unknown_changed; + MathStructure *mstruct_before_unknowns, *unknowns_mstruct; + QValueVector unknowns_entries; + bool queryClose(); + QString parsed_expression; + void keyPressEvent(QKeyEvent *e); + void fontChange(const QFont &old_font); + void saveProperties(KConfig *cfg); + void readProperties(KConfig *cfg); + +private: + + bool close_to_systray_was; + bool display_expression_status_was; + int history_height; + +}; + +class QalculateHistoryBrowser : public KTextBrowser { + + Q_OBJECT + +public: + + QalculateHistoryBrowser(QWidget *parent, const char *name); + ~QalculateHistoryBrowser(); + +protected: + + QPopupMenu *createPopupMenu(const QPoint &pos); + +}; + +class QalculateParseLabel : public QLabel { + + Q_OBJECT + +public: + + QalculateParseLabel(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateParseLabel(); + + void setText(QString text, bool break_begin, bool error_color, bool warning_color); + +protected: + + QString parsetext; + bool bb, ec, wc; + void drawContents(QPainter *p); + +}; + +class QalculateButton : public QPushButton { + + Q_OBJECT + +public: + + QalculateButton(QWidget *parent = 0, const char *name = 0); + QalculateButton(const QString &text, QWidget *parent = 0, const char *name = 0); + QalculateButton(const QIconSet &icon, const QString &text, QWidget *parent = 0, const char *name = 0); + virtual ~QalculateButton(); + + void setUseMinThreeCharWidth(bool b); + void setMarkup(const QString &str); + QSize sizeHint() const; + +private: + + bool umtcw; + +}; + +class QalculateStyleSheet : public QStyleSheet { + + Q_OBJECT + +public: + + QalculateStyleSheet(QObject *parent = 0, const char *name = 0); + virtual ~QalculateStyleSheet(); + + void scaleFont(QFont &font, int logicalSize) const; + +}; + +class QalculateRPNStackListView : public KListView { + + Q_OBJECT + +public: + + QalculateRPNStackListView(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateRPNStackListView(); + +protected: + + void keyPressEvent(QKeyEvent *e); + +}; + +class QalculateModeDialog : public KDialogBase { + + Q_OBJECT + + protected: + + KKeyButton *keyButton; + KComboBox *modeCombo; + + public: + + QalculateModeDialog(QWidget *parent); + virtual ~QalculateModeDialog(); + + QString modeName(); + const KShortcut &modeShortcut(); + + public slots: + + void slotOk(); + void updateShortcut(const KShortcut&); + void modeSelected(int); + +}; + +#endif // QALCULATE_KWINDOW_H diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..157653f --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,306 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "kqalculate.h" +#include "preferences.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 recent_functions_pre; +extern QValueVector recent_variables_pre; +extern QValueVector 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.
Ex. 5 + 2 / 3")); + } else { + mainWin->resultLabel->setText("
 
= 0
"); + } + + qApp->processEvents(); + + //exchange rates + if(first_qalculate_run) { + if(KMessageBox::questionYesNo(mainWin, i18n("You need to download exchange rates to be able to convert between different currencies. You can later get current exchange rates by selecting \"Update Exchange Rates\" under the File menu.\n\nDo you want to fetch exchange rates now from the Internet?"), i18n("Update exchange rates?")) == KMessageBox::Yes) { + qApp->processEvents(); + mainWin->fetch_exchange_rates(5); + } + qApp->processEvents(); + } else if(fetch_exchange_rates_at_startup) { + mainWin->fetch_exchange_rates(5); + qApp->processEvents(); + } + + CALCULATOR->loadExchangeRates(); + + string ans_str = i18n("ans").ascii(); + vans[0] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str, m_undefined, i18n("Last Answer").ascii(), false)); + vans[0]->addName(i18n("answer").ascii()); + vans[0]->addName(ans_str + "1"); + vans[1] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "2", m_undefined, i18n("Answer 2").ascii(), false)); + vans[2] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "3", m_undefined, i18n("Answer 3").ascii(), false)); + vans[3] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "4", m_undefined, i18n("Answer 4").ascii(), false)); + vans[4] = (KnownVariable*) CALCULATOR->addVariable(new KnownVariable(i18n("Temporary").ascii(), ans_str + "5", m_undefined, i18n("Answer 5").ascii(), false)); + + //load global definitions + if(load_global_defs && !CALCULATOR->loadGlobalDefinitions()) { + KMessageBox::error(mainWin, i18n("Failed to load global definitions!"), i18n("Error")); + qApp->processEvents(); + } + + //load local definitions + CALCULATOR->loadLocalDefinitions(); + + //check for calculation errros regularly + error_timer = new QTimer(mainWin); + QObject::connect(error_timer, SIGNAL(timeout()), mainWin, SLOT(onErrorTimeout())); + + generate_units_tree_struct(); + generate_functions_tree_struct(); + generate_variables_tree_struct(); + mainWin->create_fmenu(); + mainWin->create_vmenu(); + mainWin->create_umenu(); + mainWin->create_toumenu(); + mainWin->create_setpmenu(); + + for(int i = ((int) recent_functions_pre.size()) - 1; i >= 0; i--) { + mainWin->function_inserted(CALCULATOR->getActiveFunction(recent_functions_pre[i].ascii())); + } + for(int i = ((int) recent_variables_pre.size()) - 1; i >= 0; i--) { + mainWin->variable_inserted(CALCULATOR->getActiveVariable(recent_variables_pre[i].ascii())); + } + for(int i = ((int) recent_units_pre.size()) - 1; i >= 0; i--) { + Unit *u = CALCULATOR->getActiveUnit(recent_units_pre[i].ascii()); + if(!u) u = CALCULATOR->getCompositeUnit(recent_units_pre[i].ascii()); + mainWin->unit_inserted(u); + } + + mainWin->update_completion(); + + int pipe_wr[] = {0, 0}; + pipe(pipe_wr); + view_pipe_r = fdopen(pipe_wr[0], "r"); + view_pipe_w = fdopen(pipe_wr[1], "w"); + pthread_attr_init(&view_thread_attr); + pthread_create(&view_thread, &view_thread_attr, view_proc, view_pipe_r); + + int pipe_wr2[] = {0, 0}; + pipe(pipe_wr2); + command_pipe_r = fdopen(pipe_wr2[0], "r"); + command_pipe_w = fdopen(pipe_wr2[1], "w"); + pthread_attr_init(&command_thread_attr); + command_thread_started = false; + + QObject::connect(qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit())); + QObject::connect(qApp, SIGNAL(aboutToQuit()), mainWin, SLOT(aboutToQuit())); + + error_timer->start(100); + + if(!calc_arg.isEmpty()) { + mainWin->execute_expression(); + } + +} + +class QalculateApp : public KUniqueApplication { + +public: + + bool started; + + QalculateApp() {started = false;} + virtual ~QalculateApp() {} + + int newInstance() { + if(mainWin && started) { + + KCmdLineArgs* args = KCmdLineArgs::parsedArgs(); + QString calc_arg = parse_expression_arguments(args); + args->clear(); + +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + KWin::Info info = KWin::info(mainWin->winId()); + KWin::setOnDesktop(mainWin->winId(), KWin::currentDesktop()); + mainWin->move(info.geometry.topLeft()); +#else + KWin::WindowInfo info = KWin::windowInfo(mainWin->winId(), (unsigned long) NET::WMGeometry); + KWin::setOnDesktop(mainWin->winId(), KWin::currentDesktop()); + mainWin->move(info.geometry().topLeft()); +#endif + mainWin->setShown(true); + mainWin->show(); + mainWin->raise(); +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + KWin::setActiveWindow(mainWin->winId()); +#else + KWin::activateWindow(mainWin->winId()); +#endif + + if(!calc_arg.isEmpty()) { + mainWin->expressionEdit->setText(calc_arg); + mainWin->execute_expression(); + } + + return 0; + } else { + if(isRestored() && KMainWindow::canBeRestored(1)) { + create_qalculate_window(this); + setMainWidget(mainWin); + mainWin->restore(1, false); + start_qalculate(); + } else { + create_qalculate_window(this); + setMainWidget(mainWin); + mainWin->show(); + start_qalculate(); + } + started = true; + return KUniqueApplication::newInstance(); + } + started = true; + return 0; + } + +}; + +int main(int argc, char **argv) { + + mainWin = NULL; + + KAboutData about(PACKAGE, I18N_NOOP("Qalculate!"), version, description, KAboutData::License_GPL, "(C) 2005-2006 Niklas Knutsson", 0, "http://qalculate.sourceforge.net/", "nique769@users.sourceforge.net"); + about.addAuthor("Niklas Knutsson", 0, "nq@altern.org"); + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions(options); + KUniqueApplication::addCmdLineOptions(); + + if(!QalculateApp::start()) { + return 0; + } + + QalculateApp app; + + return app.exec(); + +} + + diff --git a/src/preferences.cpp b/src/preferences.cpp new file mode 100644 index 0000000..658e5ec --- /dev/null +++ b/src/preferences.cpp @@ -0,0 +1,865 @@ +/*************************************************************************** + * Copyright (C) 2005-2007 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "preferences.h" +#include "kqalculate.h" +#include "qalculate_kde_utils.h" +#include "qalculateexpressionedit.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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 recent_functions; +extern vector recent_variables; +extern vector recent_units; +QValueVector recent_functions_pre; +QValueVector recent_variables_pre; +QValueVector recent_units_pre; + +extern QWidget *expressionWidget; +extern KQalculate *mainWin; +QStringList expression_history; + +bool show_keypad, show_history, show_stack; + +vector modes; + +QValueVector inhistory; +QValueVector inhistory_type; +QValueVector 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("

", "

"); + } + 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] += "
"; + 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::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::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("
") < 0) { + fprintf(file, "%s\n", inhistory[i].ascii()); + } else { + QStringList slist = QStringList::split("
", inhistory[i], true); + for(QStringList::size_type i2 = 0; i2 < slist.size(); i2++) { + if(i2 == 0) fprintf(file, "%s\n", slist[i2].ascii()); + else fprintf(file, "history_continued=%s\n", slist[i2].ascii()); + } + } + } + fprintf(file, "recent_functions="); + for(int i = (int) (recent_functions.size()) - 1; i >= 0; i--) { + fprintf(file, "%s", recent_functions[i]->referenceName().c_str()); + if(i != 0) fprintf(file, ","); + } + fprintf(file, "\n"); + fprintf(file, "recent_variables="); + for(int i = (int) (recent_variables.size()) - 1; i >= 0; i--) { + fprintf(file, "%s", recent_variables[i]->referenceName().c_str()); + if(i != 0) fprintf(file, ","); + } + fprintf(file, "\n"); + fprintf(file, "recent_units="); + for(int i = (int) (recent_units.size()) - 1; i >= 0; i--) { + fprintf(file, "%s", recent_units[i]->referenceName().c_str()); + if(i != 0) fprintf(file, ","); + } + fprintf(file, "\n"); + if(mode) + set_saved_mode(); + for(size_t i = 1; i < modes.size(); i++) { + if(i == 1) { + fprintf(file, "\n[Mode]\n"); + } else { + fprintf(file, "\n[Mode %s]\n", modes[i].name.ascii()); + if(!modes[i].shortcut.toString().isNull()) fprintf(file, "shortcut=%s\n", modes[i].shortcut.toString().ascii()); + } + fprintf(file, "min_deci=%i\n", modes[i].po.min_decimals); + fprintf(file, "use_min_deci=%i\n", modes[i].po.use_min_decimals); + fprintf(file, "max_deci=%i\n", modes[i].po.max_decimals); + fprintf(file, "use_max_deci=%i\n", modes[i].po.use_max_decimals); + fprintf(file, "precision=%i\n", modes[i].precision); + fprintf(file, "min_exp=%i\n", modes[i].po.min_exp); + fprintf(file, "negative_exponents=%i\n", modes[i].po.negative_exponents); + fprintf(file, "sort_minus_last=%i\n", modes[i].po.sort_options.minus_last); + fprintf(file, "number_fraction_format=%i\n", modes[i].po.number_fraction_format); + fprintf(file, "use_prefixes=%i\n", modes[i].po.use_unit_prefixes); + fprintf(file, "abbreviate_names=%i\n", modes[i].po.abbreviate_names); + fprintf(file, "all_prefixes_enabled=%i\n", modes[i].po.use_all_prefixes); + fprintf(file, "denominator_prefix_enabled=%i\n", modes[i].po.use_denominator_prefix); + fprintf(file, "place_units_separately=%i\n", modes[i].po.place_units_separately); + fprintf(file, "auto_post_conversion=%i\n", modes[i].eo.auto_post_conversion); + fprintf(file, "number_base=%i\n", modes[i].po.base); + fprintf(file, "number_base_expression=%i\n", modes[i].eo.parse_options.base); + fprintf(file, "read_precision=%i\n", modes[i].eo.parse_options.read_precision); + fprintf(file, "assume_denominators_nonzero=%i\n", modes[i].eo.assume_denominators_nonzero); + fprintf(file, "warn_about_denominators_assumed_nonzero=%i\n", modes[i].eo.warn_about_denominators_assumed_nonzero); + fprintf(file, "structuring=%i\n", modes[i].eo.structuring); + fprintf(file, "angle_unit=%i\n", modes[i].eo.parse_options.angle_unit); + fprintf(file, "functions_enabled=%i\n", modes[i].eo.parse_options.functions_enabled); + fprintf(file, "variables_enabled=%i\n", modes[i].eo.parse_options.variables_enabled); + fprintf(file, "calculate_functions=%i\n", modes[i].eo.calculate_functions); + fprintf(file, "calculate_variables=%i\n", modes[i].eo.calculate_variables); + fprintf(file, "sync_units=%i\n", modes[i].eo.sync_units); + fprintf(file, "unknownvariables_enabled=%i\n", modes[i].eo.parse_options.unknowns_enabled); + fprintf(file, "units_enabled=%i\n", modes[i].eo.parse_options.units_enabled); + fprintf(file, "allow_complex=%i\n", modes[i].eo.allow_complex); + fprintf(file, "allow_infinite=%i\n", modes[i].eo.allow_infinite); + fprintf(file, "indicate_infinite_series=%i\n", modes[i].po.indicate_infinite_series); + fprintf(file, "show_ending_zeroes=%i\n", modes[i].po.show_ending_zeroes); + fprintf(file, "round_halfway_to_even=%i\n", modes[i].po.round_halfway_to_even); + fprintf(file, "approximation=%i\n", modes[i].eo.approximation); + fprintf(file, "in_rpn_mode=%i\n", modes[i].rpn_mode); + fprintf(file, "rpn_syntax=%i\n", modes[i].eo.parse_options.rpn); + fprintf(file, "limit_implicit_multiplication=%i\n", modes[i].eo.parse_options.limit_implicit_multiplication); + fprintf(file, "spacious=%i\n", modes[i].po.spacious); + fprintf(file, "excessive_parenthesis=%i\n", modes[i].po.excessive_parenthesis); + fprintf(file, "short_multiplication=%i\n", modes[i].po.short_multiplication); + fprintf(file, "default_assumption_type=%i\n", modes[i].at); + fprintf(file, "default_assumption_sign=%i\n", modes[i].as); + } + + fprintf(file, "\n[Plotting]\n"); + fprintf(file, "plot_legend_placement=%i\n", default_plot_legend_placement); + fprintf(file, "plot_style=%i\n", default_plot_style); + fprintf(file, "plot_smoothing=%i\n", default_plot_smoothing); + fprintf(file, "plot_display_grid=%i\n", default_plot_display_grid); + fprintf(file, "plot_full_border=%i\n", default_plot_full_border); + fprintf(file, "plot_min=%s\n", default_plot_min.ascii()); + fprintf(file, "plot_max=%s\n", default_plot_max.ascii()); + fprintf(file, "plot_step=%s\n", default_plot_step.ascii()); + fprintf(file, "plot_sampling_rate=%i\n", default_plot_sampling_rate); + fprintf(file, "plot_use_sampling_rate=%i\n", default_plot_use_sampling_rate); + fprintf(file, "plot_variable=%s\n", default_plot_variable.ascii()); + fprintf(file, "plot_rows=%i\n", default_plot_rows); + fprintf(file, "plot_type=%i\n", default_plot_type); + fprintf(file, "plot_color=%i\n", default_plot_color); + fprintf(file, "enable_plot_expression_completion=%i\n", enable_plot_expression_completion); + + + fclose(file); + +} diff --git a/src/preferences.h b/src/preferences.h new file mode 100644 index 0000000..9547989 --- /dev/null +++ b/src/preferences.h @@ -0,0 +1,42 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef PREFERENCES_H +#define PREFERENCES_H + +enum { + QALCULATE_HISTORY_EXPRESSION, + QALCULATE_HISTORY_TRANSFORMATION, + QALCULATE_HISTORY_RESULT, + QALCULATE_HISTORY_RESULT_APPROXIMATE, + QALCULATE_HISTORY_PARSE, + QALCULATE_HISTORY_PARSE_APPROXIMATE, + QALCULATE_HISTORY_WARNING, + QALCULATE_HISTORY_ERROR, + QALCULATE_HISTORY_OLD, + QALCULATE_HISTORY_REGISTER_MOVED +}; + +void save_mode(); + +void load_preferences(); +void save_preferences(bool mode = false); + +#endif diff --git a/src/qalculate_kde.desktop b/src/qalculate_kde.desktop new file mode 100644 index 0000000..c01c30b --- /dev/null +++ b/src/qalculate_kde.desktop @@ -0,0 +1,13 @@ +[Desktop Entry] +Name=Qalculate! +GenericName=Scientific Calculator +Exec=qalculate-kde +Icon=qalculate_kde +Type=Application +DocPath=qalculate_kde/index.html +Categories=Qt;KDE;Utility;Science; +Terminal=false +X-DCOP-ServiceType=Unique +X-DCOP-ServiceName=qalculate_kde +X-KDE-StartupNotify=true +Comment=Powerful and easy to use desktop calculator diff --git a/src/qalculate_kde_utils.cpp b/src/qalculate_kde_utils.cpp new file mode 100644 index 0000000..5bcb8c5 --- /dev/null +++ b/src/qalculate_kde_utils.cpp @@ -0,0 +1,307 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include "qalculate_kde_utils.h" +#include +#include +#include +#include +#include +#include +#include "kqalculate.h" + +tree_struct function_cats, unit_cats, variable_cats; +vector ia_units, ia_variables, ia_functions; +vector recent_functions; +vector recent_variables; +vector 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::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::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::iterator it; + + for(size_t i = 0; i < CALCULATOR->functions.size(); i++) { + if(!CALCULATOR->functions[i]->isActive()) { + //deactivated function + b = false; + for(size_t i3 = 0; i3 < ia_functions.size(); i3++) { + f = (MathFunction*) ia_functions[i3]; + if(CALCULATOR->functions[i]->title() < f->title()) { + b = true; + ia_functions.insert(ia_functions.begin() + i3, (void*) CALCULATOR->functions[i]); + break; + } + } + if(!b) ia_functions.push_back((void*) CALCULATOR->functions[i]); + } else { + tree_struct *item = &function_cats; + if(!CALCULATOR->functions[i]->category().empty()) { + cat = CALCULATOR->functions[i]->category(); + cat_i = cat.find("/"); cat_i_prev = 0; + b = false; + while(true) { + if(cat_i == string::npos) { + cat_sub = cat.substr(cat_i_prev, cat.length() - cat_i_prev); + } else { + cat_sub = cat.substr(cat_i_prev, cat_i - cat_i_prev); + } + b = false; + for(it = item->items.begin(); it != item->items.end(); ++it) { + if(cat_sub == it->item) { + item = &*it; + b = true; + break; + } + } + if(!b) { + tree_struct cat; + item->items.push_back(cat); + it = item->items.end(); + --it; + it->parent = item; + item = &*it; + item->item = cat_sub; + } + if(cat_i == string::npos) { + break; + } + cat_i_prev = cat_i + 1; + cat_i = cat.find("/", cat_i_prev); + } + } + b = false; + for(size_t i3 = 0; i3 < item->objects.size(); i3++) { + f = (MathFunction*) item->objects[i3]; + if(CALCULATOR->functions[i]->title() < f->title()) { + b = true; + item->objects.insert(item->objects.begin() + i3, (void*) CALCULATOR->functions[i]); + break; + } + } + if(!b) item->objects.push_back((void*) CALCULATOR->functions[i]); + } + } + + function_cats.sort(); + +} diff --git a/src/qalculate_kde_utils.h b/src/qalculate_kde_utils.h new file mode 100644 index 0000000..2632739 --- /dev/null +++ b/src/qalculate_kde_utils.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#ifndef QALCULATE_KDE_UTILS_H +#define QALCULATE_KDE_UTILS_H + +#include +#undef insertItem +#undef addItem +#undef setItem +#undef getItem + +#include +#include + +class QLabel; +class QLineEdit; + +struct tree_struct { + string item; + list items; + list::iterator it; + list::reverse_iterator rit; + vector objects; + tree_struct *parent; + void sort() { + items.sort(); + for(list::iterator it = items.begin(); it != items.end(); ++it) { + it->sort(); + } + } + bool operator < (tree_struct &s1) const { + return item < s1.item; + } +}; +struct mode_struct { + PrintOptions po; + EvaluationOptions eo; + AssumptionType at; + AssumptionSign as; + int precision; + QString name; + bool rpn_mode; + KShortcut shortcut; +}; + +void insert_text_in_expression(const QString &str); +bool is_answer_variable(Variable *v); +QString get_value_string(const MathStructure &mstruct_, bool rlabel = false, Prefix *prefix = NULL); +void set_name_label_and_entry(ExpressionItem *item, QLineEdit *entry, QLabel *label); +bool can_display_unicode_string_function(const char *str, void *arg); +void generate_units_tree_struct(); +void generate_functions_tree_struct(); +void generate_variables_tree_struct(); +size_t save_mode_as(QString name, bool *new_mode = NULL); + +#endif diff --git a/src/qalculate_kdeui.rc b/src/qalculate_kdeui.rc new file mode 100644 index 0000000..eae44d9 --- /dev/null +++ b/src/qalculate_kdeui.rc @@ -0,0 +1,168 @@ + + + + &File + &New + + + + + + + + + + + + + + + + + + + + + + + &Edit + + + + + + + + + &Set Prefix + + &Convert To Unit + + + + + + + + + + + + + + + &Mode + Number Base + + + + + + + + + + + + Numerical Display + + + + + + + + + + + + + Fractional Display + + + + + + Unit Display + + + + + + + + + + Angle Unit + + + + + + + + Enabled Objects + + + + + + + + + + + + Approximation + + + + + Assumptions + + + + + + + + + + + + + + + + Algebraic Mode + + + + + + + + + + + + + + + + + Meta Modes + + + + + + + Fu&nctions + + &Variables + + &Units + + + \ No newline at end of file diff --git a/src/qalculatebuttonwithdata.cpp b/src/qalculatebuttonwithdata.cpp new file mode 100644 index 0000000..0b4ced7 --- /dev/null +++ b/src/qalculatebuttonwithdata.cpp @@ -0,0 +1,37 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculatebuttonwithdata.h" + +QalculateButtonWithData::QalculateButtonWithData(void *data, const QString & text, QWidget *parent, const char *name) : QPushButton(text, parent, name) { + user_data = data; + QObject::connect(this, SIGNAL(clicked()), this, SLOT(emitClickedWithData())); +} +QalculateButtonWithData::QalculateButtonWithData(void *data, const QIconSet & icon, const QString & text, QWidget * parent, const char * name) : QPushButton(icon, text, parent, name) { + user_data = data; + QObject::connect(this, SIGNAL(clicked()), this, SLOT(emitClickedWithData())); +} +QalculateButtonWithData::~QalculateButtonWithData() {} +void QalculateButtonWithData::emitClickedWithData() { + emit clickedWithData(user_data); +} + + + +#include "qalculatebuttonwithdata.moc" diff --git a/src/qalculatebuttonwithdata.h b/src/qalculatebuttonwithdata.h new file mode 100644 index 0000000..b3281a3 --- /dev/null +++ b/src/qalculatebuttonwithdata.h @@ -0,0 +1,48 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEBUTTONWITHDATA_H +#define QALCULATEBUTTONWITHDATA_H + +#include + +/** +@author Niklas Knutsson +*/ +class QalculateButtonWithData : public QPushButton { + Q_OBJECT + +public: + + QalculateButtonWithData(void *data, const QString & text, QWidget *parent, const char *name = 0); + QalculateButtonWithData(void *data, const QIconSet & icon, const QString & text, QWidget * parent, const char * name = 0); + virtual ~QalculateButtonWithData(); + void *user_data; + +protected slots: + + void emitClickedWithData(); + +signals: + + void clickedWithData(void*); + +}; + +#endif diff --git a/src/qalculateconvertnumberbasesdialog.cpp b/src/qalculateconvertnumberbasesdialog.cpp new file mode 100644 index 0000000..79585c1 --- /dev/null +++ b/src/qalculateconvertnumberbasesdialog.cpp @@ -0,0 +1,122 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateconvertnumberbasesdialog.h" +#include "qalculate_kde_utils.h" +#include +#include +#include +#include +#include + +extern EvaluationOptions evalops; + +QalculateConvertNumberBasesDialog::QalculateConvertNumberBasesDialog(QWidget *parent, const char *name) + : KDialogBase(parent, name, false, i18n("Number Bases"), Close, Close) { + + actionButton(Close)->setAutoDefault(false); + actionButton(Close)->setDefault(false); + + QGrid *grid = makeGridMainWidget(2, Qt::Horizontal); + new QLabel(i18n("Decimal:"), grid); + decimalEdit = new KLineEdit(grid); + decimalEdit->setAlignment(Qt::AlignRight); + QObject::connect(decimalEdit, SIGNAL(textChanged(const QString&)), this, SLOT(setDecimalValue(const QString&))); + new QLabel(i18n("Binary:"), grid); + binaryEdit = new KLineEdit(grid); + binaryEdit->setAlignment(Qt::AlignRight); + QObject::connect(binaryEdit, SIGNAL(textChanged(const QString&)), this, SLOT(setBinaryValue(const QString&))); + new QLabel(i18n("Octal:"), grid); + octalEdit = new KLineEdit(grid); + octalEdit->setAlignment(Qt::AlignRight); + QObject::connect(octalEdit, SIGNAL(textChanged(const QString&)), this, SLOT(setOctalValue(const QString&))); + new QLabel(i18n("Hexadecimal:"), grid); + hexadecimalEdit = new KLineEdit(grid); + hexadecimalEdit->setAlignment(Qt::AlignRight); + QObject::connect(hexadecimalEdit, SIGNAL(textChanged(const QString&)), this, SLOT(setHexadecimalValue(const QString&))); + + decimalEdit->setFocus(); + +} + + +QalculateConvertNumberBasesDialog::~QalculateConvertNumberBasesDialog() {} + +void QalculateConvertNumberBasesDialog::setDecimalValue(const QString &qstr) { + string str = qstr.ascii(); + remove_blank_ends(str); + if(str.empty()) return; + if(is_in(OPERATORS EXP, str[str.length() - 1])) return; + EvaluationOptions eo; + eo.parse_options.angle_unit = evalops.parse_options.angle_unit; + MathStructure value = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo); + updateEntries(&value, 10); +} +void QalculateConvertNumberBasesDialog::setBinaryValue(const QString &qstr) { + string str = qstr.ascii(); + remove_blank_ends(str); + if(str.empty()) return; + if(is_in(OPERATORS EXP, str[str.length() - 1])) return; + EvaluationOptions eo; + eo.parse_options.base = BASE_BINARY; + eo.parse_options.angle_unit = evalops.parse_options.angle_unit; + MathStructure value = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo); + updateEntries(&value, 2); +} +void QalculateConvertNumberBasesDialog::setOctalValue(const QString &qstr) { + string str = qstr.ascii(); + remove_blank_ends(str); + if(str.empty()) return; + if(is_in(OPERATORS EXP, str[str.length() - 1])) return; + EvaluationOptions eo; + eo.parse_options.base = BASE_OCTAL; + eo.parse_options.angle_unit = evalops.parse_options.angle_unit; + MathStructure value = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo); + updateEntries(&value, 8); +} +void QalculateConvertNumberBasesDialog::setHexadecimalValue(const QString &qstr) { + string str = qstr.ascii(); + remove_blank_ends(str); + if(str.empty()) return; + if(is_in(OPERATORS EXP, str[str.length() - 1])) return; + EvaluationOptions eo; + eo.parse_options.angle_unit = evalops.parse_options.angle_unit; + eo.parse_options.base = BASE_HEXADECIMAL; + MathStructure value = CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo); + updateEntries(&value, 16); +} + +void QalculateConvertNumberBasesDialog::updateEntries(const MathStructure *value, int base) { + decimalEdit->blockSignals(true); + binaryEdit->blockSignals(true); + octalEdit->blockSignals(true); + hexadecimalEdit->blockSignals(true); + PrintOptions po; + po.number_fraction_format = FRACTION_DECIMAL; + if(base != 10) {po.base = 10; decimalEdit->setText(value->print(po).c_str());} + if(base != 2) {po.base = 2; binaryEdit->setText(value->print(po).c_str());} + if(base != 8) {po.base = 8; octalEdit->setText(value->print(po).c_str());} + if(base != 16) {po.base = 16; hexadecimalEdit->setText(value->print(po).c_str());} + decimalEdit->blockSignals(false); + binaryEdit->blockSignals(false); + octalEdit->blockSignals(false); + hexadecimalEdit->blockSignals(false); +} + +#include "qalculateconvertnumberbasesdialog.moc" diff --git a/src/qalculateconvertnumberbasesdialog.h b/src/qalculateconvertnumberbasesdialog.h new file mode 100644 index 0000000..943fede --- /dev/null +++ b/src/qalculateconvertnumberbasesdialog.h @@ -0,0 +1,53 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATECONVERTNUMBERBASESDIALOG_H +#define QALCULATECONVERTNUMBERBASESDIALOG_H + +#include + +class KLineEdit; +class MathStructure; + +/** +@author Niklas Knutsson +*/ +class QalculateConvertNumberBasesDialog : public KDialogBase { + Q_OBJECT +public: + QalculateConvertNumberBasesDialog(QWidget *parent = 0, const char *name = 0); + + virtual ~QalculateConvertNumberBasesDialog(); + + KLineEdit *binaryEdit, *octalEdit, *decimalEdit, *hexadecimalEdit; + +public slots: + + void setDecimalValue(const QString&); + void setBinaryValue(const QString&); + void setOctalValue(const QString&); + void setHexadecimalValue(const QString&); + +protected: + + void updateEntries(const MathStructure *value, int base); + +}; + +#endif diff --git a/src/qalculateconvertunitsdialog.cpp b/src/qalculateconvertunitsdialog.cpp new file mode 100644 index 0000000..f3ebb61 --- /dev/null +++ b/src/qalculateconvertunitsdialog.cpp @@ -0,0 +1,205 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateconvertunitsdialog.h" +#include "qalculate_kde_utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern tree_struct unit_cats; +extern vector ia_units; +extern PrintOptions printops; +extern EvaluationOptions evalops; + + +QalculateConvertUnitsDialog::QalculateConvertUnitsDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Convert"), Ok | Apply | Cancel | Details, Ok, true) { + + setButtonText(Details, i18n("Selector")); + + selected_category = ""; + block_unit_convert = true; + + QVBox *box = makeVBoxMainWidget(); + new QLabel(i18n("Unit expression:"), box); + unitExpressionEdit = new KLineEdit(box); + + QVBox *box_d = new QVBox(this); + box_d->setSpacing(spacingHint()); + new QWidget(box_d); + + QSplitter *splitter = new QSplitter(Qt::Vertical, box_d); + splitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + + setDetailsWidget(box_d); + + categoryView = new KListView(splitter); + categoryView->addColumn(i18n("Category")); + categoryView->setRootIsDecorated(false); + categoryView->setFullWidth(true); + + unitView = new KListView(splitter); + unitView->addColumn(i18n("Unit")); + unitView->setRootIsDecorated(false); + unitView->setFullWidth(true); + + unitExpressionEdit->setFocus(); + + connect(unitView, SIGNAL(selectionChanged()), this, SLOT(unitSelected())); + connect(categoryView, SIGNAL(selectionChanged()), this, SLOT(categorySelected())); + +} + +QalculateConvertUnitsDialog::~QalculateConvertUnitsDialog() {} + +void QalculateConvertUnitsDialog::updateUnitTree() { + unitItems.clear(); + categoryItems.clear(); + categoryView->clear(); + QListViewItem *i = new KListViewItem(categoryView, i18n("All")), *i2; + categoryItems[i] = i18n("All"); + i->setOpen(true); + QString str; + tree_struct *item, *item2; + unit_cats.it = unit_cats.items.begin(); + if(unit_cats.it != unit_cats.items.end()) { + item = &*unit_cats.it; + ++unit_cats.it; + item->it = item->items.begin(); + } else { + item = NULL; + } + str = ""; + i2 = i; + while(item) { + str += "/"; + str += item->item.c_str(); + i = new KListViewItem(i2, item->item.c_str()); + i->setOpen(false); + categoryItems[i] = str; + if(str == selected_category) { + categoryView->ensureItemVisible(i); + categoryView->setSelected(i, true); + } + while(item && item->it == item->items.end()) { + int str_i = str.findRev("/"); + if(str_i < 0) { + str = ""; + } else { + str.truncate(str_i); + } + item = item->parent; + i = i->parent(); + i2 = i; + } + if(item) { + item2 = &*item->it; + if(item->it == item->items.begin()) + i2 = i; + ++item->it; + item = item2; + item->it = item->items.begin(); + } + } + if(!unit_cats.objects.empty()) { + //add "Uncategorized" category if there are units without category + i = new KListViewItem(categoryView, i18n("Uncategorized")); + categoryItems[i] = i18n("Uncategorized"); + if(selected_category == i18n("Uncategorized")) { + categoryView->ensureItemVisible(i); + categoryView->setSelected(i, true); + } + } + if(!categoryView->selectedItem()) { + //if no category has been selected (previously selected has been renamed/deleted), select "All" + selected_category = i18n("All"); + QListViewItemIterator it(categoryView); + if(it.current()) + categoryView->setSelected(it.current(), true); + } +} + +void QalculateConvertUnitsDialog::unitSelected() { + QListViewItem *selected = unitView->selectedItem(); + if(selected) { + Unit *u = unitItems[selected]; + if(!CALCULATOR->stillHasUnit(u)) { + KMessageBox::error(this, i18n("Unit does not exist anymore.")); + emit unitsChanged(); + return; + } + unitExpressionEdit->setText(u->print(false, printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) unitExpressionEdit).c_str()); + unitView->selectAll(false); + if(!block_unit_convert) actionButton(Apply)->animateClick(); + } +} + +void QalculateConvertUnitsDialog::addUnitTreeItem(Unit *u) { + QListViewItem *i = new KListViewItem(unitView, u->title(true).c_str()); + unitItems[i] = u; +} + + +void QalculateConvertUnitsDialog::categorySelected() { + block_unit_convert = true; + QListViewItem *selected = categoryView->selectedItem(); + bool no_cat = false, b_all = false; + unitView->clear(); + unitItems.clear(); + if(!selected) { + selected_category = ""; + return; + } + selected_category = categoryItems[selected]; + if(selected_category == i18n("All")) { + b_all = true; + } else if(selected_category == i18n("Uncategorized")) { + no_cat = true; + } + if(!b_all && !no_cat && selected_category[0] == '/') { + string str = selected_category.ascii(); + str.erase(str.begin()); + for(size_t i = 0; i < CALCULATOR->units.size(); i++) { + if(CALCULATOR->units[i]->isActive() && !CALCULATOR->units[i]->isHidden() && CALCULATOR->units[i]->category().substr(0, selected_category.length() - 1) == str) { + addUnitTreeItem(CALCULATOR->units[i]); + } + } + } else { + string str = selected_category.ascii(); + for(size_t i = 0; i < CALCULATOR->units.size(); i++) { + if(CALCULATOR->units[i]->isActive() && !CALCULATOR->units[i]->isHidden() && (b_all || (no_cat && CALCULATOR->units[i]->category().empty()) || CALCULATOR->units[i]->category() == str)) { + addUnitTreeItem(CALCULATOR->units[i]); + } + } + } + block_unit_convert = false; +} + + +#include "qalculateconvertunitsdialog.moc" diff --git a/src/qalculateconvertunitsdialog.h b/src/qalculateconvertunitsdialog.h new file mode 100644 index 0000000..7c6991c --- /dev/null +++ b/src/qalculateconvertunitsdialog.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATECONVERTUNITSDIALOG_H +#define QALCULATECONVERTUNITSDIALOG_H + +#include +#include + +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 unitItems; + QMap categoryItems; + + KListView *categoryView; + KListView *unitView; + + QString selected_category; + bool block_unit_convert; + +public slots: + + void updateUnitTree(); + void unitSelected(); + void categorySelected(); + +signals: + + void unitsChanged(); + +}; + +#endif diff --git a/src/qalculatedatasetsdialog.cpp b/src/qalculatedatasetsdialog.cpp new file mode 100644 index 0000000..4468788 --- /dev/null +++ b/src/qalculatedatasetsdialog.cpp @@ -0,0 +1,506 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculatedatasetsdialog.h" + +#include "qalculateeditdatasetdialog.h" +#include "qalculateeditdataobjectdialog.h" +#include "qalculate_kde_utils.h" +#include "qalculatebuttonwithdata.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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("<", "<"); + str2.replace(">", ">"); + str += str2; + str += "

"; + } + str += ""; + str += i18n("Properties"); + str += "
"; + dp = ds->getFirstProperty(&pit); + while(dp) { + if(!dp->isHidden()) { + if(!dp->title(false).empty()) { + str2 = dp->title().c_str(); + str2.replace("<", "<"); + str2.replace(">", ">"); + 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 += "
"; + if(!dp->description().empty()) { + str += ""; + str2 = dp->description().c_str(); + str2.replace("<", "<"); + str2.replace(">", ">"); + str += str2; + str += "
"; + } + } + dp = ds->getNextProperty(&pit); + } + str += "
"; + str += i18n("Data Retrieval Function"); + str += "
"; + 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 += ""; + str += ename->name.c_str(); + str += ""; + 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 += "
"; + str += ds->getName(i2).name.c_str(); + } + } + str += "
"; + str += "
"; + + if(!ds->copyright().empty()) { + str += "
"; + str2 = ds->copyright().c_str(); + str2.replace("<", "<"); + str2.replace(">", ">"); + str += str2; + str += "
"; + } + str.replace("\n", "
"); + 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 = ""; str += dp->title().c_str(); str += ":"; str += ""; + new QLabel(str, attributesGrid); + KLineEdit *le = new KLineEdit(sval, attributesGrid); + le->setReadOnly(true); + le->setFrameStyle(QFrame::NoFrame | QFrame::Plain); + QalculateButtonWithData *button = new QalculateButtonWithData((void*) dp, QIconSet(SmallIcon("editpaste")), "", attributesGrid); + QObject::connect(button, SIGNAL(clickedWithData(void*)), SLOT(insertObjectData(void*))); + } + } + dp = ds->getNextProperty(&it); + } + QWidget *widget = new QWidget(attributesGrid); + widget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); + attributesGrid->show(); + } else { + delete attributesGrid; + attributesGrid = new QGrid(3, Qt::Horizontal, attributesView->viewport()); + attributesGrid->setSpacing(spacingHint()); + attributesView->addChild(attributesGrid); + attributesGrid->show(); + selected_object = NULL; + editObjectButton->setEnabled(false); + deleteObjectButton->setEnabled(false); + } + +} + +void QalculateDataSetsDialog::deleteObject() { + UPDATE_SELECTED_DATASET + UPDATE_SELECTED_OBJECT + selected_dataset->delObject(selected_object); + selected_object = NULL; + updateObjects(); +} + +void QalculateDataSetsDialog::updateObjects() { + dataSetSelected(); +} + +void QalculateDataSetsDialog::editObject() { + UPDATE_SELECTED_DATASET + UPDATE_SELECTED_OBJECT + if(!object_edit_dialog) { + object_edit_dialog = new QalculateEditDataObjectDialog(this); + } + DataObject *o = object_edit_dialog->editDataObject(selected_dataset, selected_object); + if(o) { + selected_object = o; + updateObjects(); + } +} + +void QalculateDataSetsDialog::newObject() { + UPDATE_SELECTED_DATASET + if(!object_edit_dialog) { + object_edit_dialog = new QalculateEditDataObjectDialog(this); + } + DataObject *o = object_edit_dialog->editDataObject(selected_dataset); + if(o) { + selected_object = o; + updateObjects(); + } +} + +void QalculateDataSetsDialog::objectDoubleClicked(QListViewItem*i) { + UPDATE_SELECTED_DATASET + selected_object = objectItems[i]; + if(!selected_object) + return; + if(!object_edit_dialog) { + object_edit_dialog = new QalculateEditDataObjectDialog(this); + } + DataObject *o = object_edit_dialog->editDataObject(selected_dataset, selected_object); + if(o) { + selected_object = o; + updateObjects(); + } +} + + + +#include "qalculatedatasetsdialog.moc" diff --git a/src/qalculatedatasetsdialog.h b/src/qalculatedatasetsdialog.h new file mode 100644 index 0000000..1fa85b7 --- /dev/null +++ b/src/qalculatedatasetsdialog.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEDATASETSDIALOG_H +#define QALCULATEDATASETSDIALOG_H + +#include +#include + +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 dataSetItems; + QMap objectItems; + + DataSet *selected_dataset; + DataObject *selected_object; + + QalculateEditDataSetDialog *dataset_edit_dialog; + QalculateEditDataObjectDialog *object_edit_dialog; + +public slots: + + void updateDataSetTree(); + void dataSetDoubleClicked(QListViewItem*); + void objectDoubleClicked(QListViewItem*); + void dataSetSelected(); + void objectSelected(); + void deleteDataSet(); + void editDataSet(); + void newDataSet(); + void deleteObject(); + void editObject(); + void newObject(); + void updateObjects(); + void insertObjectData(void*); + +signals: + + void dataSetsChanged(); + +}; + +#endif diff --git a/src/qalculatedecimalsdialog.cpp b/src/qalculatedecimalsdialog.cpp new file mode 100644 index 0000000..2039b93 --- /dev/null +++ b/src/qalculatedecimalsdialog.cpp @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculatedecimalsdialog.h" + +#include +#include +#include +#include + +QalculateDecimalsDialog::QalculateDecimalsDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Decimals"), Close, Close, true) { + + QGrid *grid = makeGridMainWidget(2, Qt::Horizontal); + + new QLabel(i18n("Max decimals:"), grid); + + maxDecimalsBox = new QSpinBox(grid); + maxDecimalsBox->setButtonSymbols(QSpinBox::PlusMinus); + maxDecimalsBox->setMinValue(-1); + maxDecimalsBox->setValue(-1); + maxDecimalsBox->setSpecialValueText(i18n( "Off" )); + + new QLabel(i18n("Min decimals:"), grid); + + minDecimalsBox = new QSpinBox(grid); + minDecimalsBox->setButtonSymbols(QSpinBox::PlusMinus); + minDecimalsBox->setMinValue(0); + minDecimalsBox->setValue(0); + minDecimalsBox->setSpecialValueText(i18n( "Off" )); + + resize(QSize(300, minimumSizeHint().height()).expandedTo(minimumSizeHint())); + +} + + +QalculateDecimalsDialog::~QalculateDecimalsDialog() {} + + +#include "qalculatedecimalsdialog.moc" diff --git a/src/qalculatedecimalsdialog.h b/src/qalculatedecimalsdialog.h new file mode 100644 index 0000000..ae16d7c --- /dev/null +++ b/src/qalculatedecimalsdialog.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEDECIMALSDIALOG_H +#define QALCULATEDECIMALSDIALOG_H + +#include + +class QSpinBox; + +/** +@author Niklas Knutsson +*/ +class QalculateDecimalsDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateDecimalsDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateDecimalsDialog(); + + QSpinBox *maxDecimalsBox, *minDecimalsBox; + +}; + +#endif diff --git a/src/qalculateeditdataobjectdialog.cpp b/src/qalculateeditdataobjectdialog.cpp new file mode 100644 index 0000000..cf9e0cd --- /dev/null +++ b/src/qalculateeditdataobjectdialog.cpp @@ -0,0 +1,103 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateeditdataobjectdialog.h" +#include "qalculate_kde_utils.h" +#include +#include +#include +#include +#include +#include +#include + +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 value_entries; + QValueVector approx_menus; + string str; + while(dp) { + new QLabel(dp->title().c_str(), grid); + KLineEdit *entry = new KLineEdit(grid); + value_entries.push_back(entry); + int iapprox = -1; + if(o) { + entry->setText(o->getProperty(dp, &iapprox).c_str()); + } + new QLabel(dp->getUnitString().c_str(), grid); + KComboBox *om = new KComboBox(grid); + om->setEditable(false); + om->insertItem(i18n("Default")); + om->insertItem(i18n("Approximate")); + om->insertItem(i18n("Exact")); + approx_menus.push_back(om); + om->setCurrentItem(iapprox + 1); + dp = ds->getNextProperty(&it); + } + if(exec() == QDialog::Accepted) { + bool new_object = (o == NULL); + if(new_object) { + o = new DataObject(ds); + ds->addObject(o); + } + dp = ds->getFirstProperty(&it); + size_t i = 0; + QString val; + while(dp) { + val = value_entries[i]->text().stripWhiteSpace(); + if(!val.isEmpty()) { + o->setProperty(dp, val.ascii(), approx_menus[i]->currentItem() - 1); + } else if(!new_object) { + o->eraseProperty(dp); + } + dp = ds->getNextProperty(&it); + i++; + } + o->setUserModified(); + delete grid; + return o; + } + delete grid; + return NULL; +} + +#include "qalculateeditdataobjectdialog.moc" diff --git a/src/qalculateeditdataobjectdialog.h b/src/qalculateeditdataobjectdialog.h new file mode 100644 index 0000000..9db334b --- /dev/null +++ b/src/qalculateeditdataobjectdialog.h @@ -0,0 +1,44 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEEDITDATAOBJECTDIALOG_H +#define QALCULATEEDITDATAOBJECTDIALOG_H + +#include + +class DataObject; +class DataSet; + +/** +@author Niklas Knutsson +*/ +class QalculateEditDataObjectDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateEditDataObjectDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateEditDataObjectDialog(); + + DataObject *editDataObject(DataSet *ds, DataObject *o = NULL); + +}; + +#endif diff --git a/src/qalculateeditdatasetdialog.cpp b/src/qalculateeditdatasetdialog.cpp new file mode 100644 index 0000000..3341395 --- /dev/null +++ b/src/qalculateeditdatasetdialog.cpp @@ -0,0 +1,750 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateeditdatasetdialog.h" +#include "qalculate_kde_utils.h" +#include "qalculateeditnamesdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1 +#include +#else +#include +#endif +#include +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 +#include +#else +#include +#endif +#include +#include + +extern PrintOptions printops; +extern tree_struct function_cats; + +QalculateEditDataSetDialog::QalculateEditDataSetDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Data Set"), Ok | Cancel, Ok, false) { + + names_edit_dialog = NULL; + edited_dataset = NULL; + property_edit_dialog = NULL; + +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + tabs = new QTabWidget(this); +#else + tabs = new KTabWidget(this); +#endif + setMainWidget(tabs); + QWidget *page1 = new QWidget(this); + QWidget *page2 = new QWidget(this); + QWidget *page3 = new QWidget(this); + tabs->addTab(page1, i18n("General")); + tabs->addTab(page2, i18n("Properties")); + tabs->addTab(page3, i18n("Function")); + + QGridLayout *grid = new QGridLayout(page1, 1, 1, spacingHint()); + grid->addWidget(new QLabel(i18n("Title:"), page1), 0, 0); + titleEdit = new KLineEdit(page1); + grid->addWidget(titleEdit, 0, 1); + grid->addWidget(new QLabel(i18n("Data file:"), page1), 1, 0); + fileEdit = new KLineEdit(page1); + grid->addWidget(fileEdit, 1, 1); + grid->addWidget(new QLabel(i18n("Description:"), page1), 2, 0); +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1 + descriptionEdit = new QTextEdit(page1); +#else + descriptionEdit = new KTextEdit(page1); +#endif + descriptionEdit->setTextFormat(QTextEdit::PlainText); + grid->addMultiCellWidget(descriptionEdit, 3, 3, 0, 1); + grid->addWidget(new QLabel(i18n("Copyright:"), page1), 4, 0); +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1 + copyrightEdit = new QTextEdit(page1); +#else + copyrightEdit = new KTextEdit(page1); +#endif + copyrightEdit->setTextFormat(QTextEdit::PlainText); + grid->addMultiCellWidget(copyrightEdit, 5, 5, 0, 1); + + QVBoxLayout *vbox = new QVBoxLayout(page2, spacingHint()); + vbox->addWidget(new QLabel(i18n("Properties:"), page2)); + propertiesView = new KListView(page2); + propertiesView->addColumn(i18n("Title")); + propertiesView->addColumn(i18n("Name")); + propertiesView->addColumn(i18n("Type")); + propertiesView->setSorting(-1); + propertiesView->setRootIsDecorated(false); + vbox->addWidget(propertiesView); + QHBoxLayout *hbox = new QHBoxLayout(vbox, spacingHint()); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + newPropertyButton = new QPushButton(i18n("New"), page2); + hbox->addWidget(newPropertyButton); + editPropertyButton = new QPushButton(i18n("Edit"), page2); + hbox->addWidget(editPropertyButton); + deletePropertyButton = new QPushButton(i18n("Delete"), page2); + hbox->addWidget(deletePropertyButton); + + grid = new QGridLayout(page3, 1, 1, spacingHint()); + grid->addWidget(new QLabel(i18n("Name:"), page3), 0, 0); + nameEdit = new KLineEdit(page3); + grid->addWidget(nameEdit, 0, 1); + hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 1, 1, 0, 1); + namesLabel = new QLabel(page3); + namesLabel->setAlignment(Qt::AlignRight); + namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + hbox->addWidget(namesLabel); + namesButton = new QPushButton(i18n("Names Details"), page3); + hbox->addWidget(namesButton); + grid->addWidget(new QLabel(i18n("Object argument name:"), page3), 2, 0); + objectArgumentEdit = new KLineEdit(page3); + grid->addWidget(objectArgumentEdit, 2, 1); + grid->addWidget(new QLabel(i18n("Property argument name:"), page3), 3, 0); + propertyArgumentEdit = new KLineEdit(page3); + grid->addWidget(propertyArgumentEdit, 3, 1); + grid->addWidget(new QLabel(i18n("Default property:"), page3), 4, 0); + defaultPropertyEdit = new KLineEdit(page3); + grid->addWidget(defaultPropertyEdit, 4, 1); + grid->addItem(new QSpacerItem(5, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + + connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames())); + connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&))); + connect(newPropertyButton, SIGNAL(clicked()), this, SLOT(newProperty())); + connect(editPropertyButton, SIGNAL(clicked()), this, SLOT(editProperty())); + connect(deletePropertyButton, SIGNAL(clicked()), this, SLOT(deleteProperty())); + connect(propertiesView, SIGNAL(selectionChanged()), this, SLOT(propertySelectionChanged())); + +} + +QalculateEditDataSetDialog::~QalculateEditDataSetDialog() {} + + +void QalculateEditDataSetDialog::propertySelectionChanged() { + QListViewItem *i = propertiesView->selectedItem(); + if(i) { + editPropertyButton->setEnabled(propertiesItems[i]->isUserModified()); + deletePropertyButton->setEnabled(propertiesItems[i]->isUserModified()); + } else { + editPropertyButton->setEnabled(false); + deletePropertyButton->setEnabled(false); + } +} + +void QalculateEditDataSetDialog::updateDatasetPropertyList() { + propertiesView->clear(); + propertiesItems.clear(); + editPropertyButton->setEnabled(false); + deletePropertyButton->setEnabled(false); + QString str; + QListViewItem *i_prev = NULL; + for(size_t i = 0; i < tmp_props.size(); i++) { + if(tmp_props[i]) { + str = ""; + switch(tmp_props[i]->propertyType()) { + case PROPERTY_STRING: { + str += i18n("text"); + break; + } + case PROPERTY_NUMBER: { + if(tmp_props[i]->isApproximate()) { + str += i18n("approximate"); + str += " "; + } + str += i18n("number"); + break; + } + case PROPERTY_EXPRESSION: { + if(tmp_props[i]->isApproximate()) { + str += i18n("approximate"); + str += " "; + } + str += i18n("expression"); + break; + } + } + if(tmp_props[i]->isKey()) { + str += " ("; + str += i18n("key"); + str += ")"; + } + QListViewItem *item = new KListViewItem(propertiesView, i_prev, tmp_props[i]->title(false).c_str(), tmp_props[i]->getName().c_str(), str); + i_prev = item; + propertiesItems[item] = tmp_props[i]; + } + } +} + +void QalculateEditDataSetDialog::slotOk() { + + string str = nameEdit->text().ascii(); + remove_blank_ends(str); + if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) { + //no name -- open dialog again + tabs->setCurrentPage(2); + nameEdit->setFocus(); + KMessageBox::error(this, i18n("Empty name field")); + return; + } + //function with the same name exists -- overwrite or open dialog again + if((!edited_dataset || !edited_dataset->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->functionNameTaken(str, edited_dataset) && KMessageBox::questionYesNo(this, i18n("A function with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) { + tabs->setCurrentPage(2); + nameEdit->setFocus(); + return; + } + + DataSet *ds = edited_dataset; + bool add_func = false; + if(ds) { + //edited an existing function + ds->setTitle(titleEdit->text().ascii()); + ds->setDescription(descriptionEdit->text().ascii()); + if(ds->isLocal()) ds->setDefaultDataFile(fileEdit->text().ascii()); + } else { + //new function + ds = new DataSet(i18n("Data Sets").ascii(), "", fileEdit->text().ascii(), titleEdit->text().ascii(), descriptionEdit->text().ascii(), true); + add_func = true; + } + QString str2 = objectArgumentEdit->text().stripWhiteSpace(); + if(str2.isEmpty()) str2 = i18n("Object"); + Argument *arg = ds->getArgumentDefinition(1); + if(arg) { + arg->setName(str2.ascii()); + } + str2 = propertyArgumentEdit->text().stripWhiteSpace(); + if(str2.isEmpty()) str2 = i18n("Property"); + arg = ds->getArgumentDefinition(2); + if(arg) { + arg->setName(str2.ascii()); + } + ds->setDefaultProperty(defaultPropertyEdit->text().ascii()); + ds->setCopyright(copyrightEdit->text().ascii()); + DataPropertyIter it; + for(size_t i = 0; i < tmp_props.size();) { + if(!tmp_props[i]) { + if(tmp_props_orig[i]) ds->delProperty(tmp_props_orig[i]); + i++; + } else if(tmp_props[i]->isUserModified()) { + if(tmp_props_orig[i]) { + tmp_props_orig[i]->set(*tmp_props[i]); + i++; + } else { + ds->addProperty(tmp_props[i]); + tmp_props.erase(tmp_props.begin() + i); + } + } else { + i++; + } + } + + if(names_edit_dialog) { + names_edit_dialog->saveNames(ds, str.c_str()); + } else { + if(ds->countNames() == 0) { + ExpressionName ename(str); + ename.reference = true; + ds->setName(ename, 1); + } else { + ds->setName(str, 1); + } + } + if(add_func) { + CALCULATOR->addDataSet(ds); + ds->loadObjects(); + ds->setObjectsLoaded(true); + } + + for(size_t i = 0; i < tmp_props.size(); i++) { + if(tmp_props[i]) delete tmp_props[i]; + } + tmp_props.clear(); + tmp_props_orig.clear(); + edited_dataset = ds; + + accept(); + +} + +DataSet *QalculateEditDataSetDialog::editDataSet(DataSet *ds) { + + titleEdit->setFocus(); + + tabs->setCurrentPage(0); + if(names_edit_dialog) { + delete names_edit_dialog; + names_edit_dialog = NULL; + } + edited_dataset = ds; + if(ds) { + if(ds->isLocal()) + setCaption(i18n("Edit Data Set")); + else + setCaption(i18n("Edit Data Set (global)")); + } else { + setCaption(i18n("New Data Set")); + } + + //clear entries + fileEdit->setReadOnly(ds && !ds->isLocal()); + copyrightEdit->setReadOnly(ds && !ds->isLocal()); + nameEdit->clear(); + titleEdit->clear(); + fileEdit->clear(); + objectArgumentEdit->clear(); + propertyArgumentEdit->clear(); + defaultPropertyEdit->setText(i18n("info")); + namesLabel->clear(); + descriptionEdit->clear(); + copyrightEdit->clear(); + nameEdit->setReadOnly(false); + actionButton(Ok)->setEnabled(true); + newPropertyButton->setEnabled(TRUE); + editPropertyButton->setEnabled(FALSE); + deletePropertyButton->setEnabled(FALSE); + if(ds) { + //fill in original paramaters + set_name_label_and_entry(ds, nameEdit, namesLabel); + fileEdit->setText(ds->defaultDataFile().c_str()); + defaultPropertyEdit->setText(ds->defaultProperty().c_str()); + titleEdit->setText(ds->title(false).c_str()); + Argument *arg = ds->getArgumentDefinition(1); + if(arg) { + objectArgumentEdit->setText(arg->name().c_str()); + } + arg = ds->getArgumentDefinition(2); + if(arg) { + propertyArgumentEdit->setText(arg->name().c_str()); + } + descriptionEdit->setText(ds->description().c_str()); + copyrightEdit->setText(ds->copyright().c_str()); + DataPropertyIter it; + DataProperty *dp = ds->getFirstProperty(&it); + while(dp) { + tmp_props.push_back(new DataProperty(*dp)); + tmp_props_orig.push_back(dp); + dp = ds->getNextProperty(&it); + } + } + updateDatasetPropertyList(); + + if(exec() == QDialog::Accepted) { + ds = edited_dataset; + edited_dataset = NULL; + return ds; + } + edited_dataset = NULL; + for(size_t i = 0; i < tmp_props.size(); i++) { + if(tmp_props[i]) delete tmp_props[i]; + } + tmp_props.clear(); + tmp_props_orig.clear(); + return NULL; +} + +void QalculateEditDataSetDialog::editNames() { + if(!names_edit_dialog) { + names_edit_dialog = new QalculateEditNamesDialog(TYPE_FUNCTION, this); + names_edit_dialog->setNames(edited_dataset, nameEdit->text(), false); + } else { + names_edit_dialog->setNames(edited_dataset, nameEdit->text(), true); + } + names_edit_dialog->exec(); + names_edit_dialog->setNamesLE(nameEdit, namesLabel); +} +void QalculateEditDataSetDialog::newProperty() { + if(!property_edit_dialog) { + property_edit_dialog = new QalculateEditDataPropertyDialog(this); + } + DataProperty *dp = new DataProperty(edited_dataset); + dp->setUserModified(true); + if(property_edit_dialog->editDataProperty(dp, true)) { + tmp_props.push_back(dp); + tmp_props_orig.push_back(NULL); + updateDatasetPropertyList(); + } else { + delete dp; + } +} + +void QalculateEditDataSetDialog::editProperty() { + QListViewItem *i = propertiesView->selectedItem(); + if(i == NULL) return; + if(!property_edit_dialog) { + property_edit_dialog = new QalculateEditDataPropertyDialog(this); + } + if(property_edit_dialog->editDataProperty(propertiesItems[i])) { + updateDatasetPropertyList(); + } +} +void QalculateEditDataSetDialog::deleteProperty() { + QListViewItem *i = propertiesView->selectedItem(); + if(i == NULL) return; + if(propertiesItems[i]->isUserModified()) { + for(size_t index = 0; index < tmp_props.size(); index++) { + if(tmp_props[index] == propertiesItems[i]) { + if(tmp_props_orig[index]) { + tmp_props[index] = NULL; + } else { + tmp_props.erase(tmp_props.begin() + index); + tmp_props_orig.erase(tmp_props_orig.begin() + index); + } + break; + } + } + updateDatasetPropertyList(); + } +} + +void QalculateEditDataSetDialog::nameChanged(const QString &name) { + if(name.isNull()) return; + if(!CALCULATOR->functionNameIsValid(name.ascii())) { + nameEdit->blockSignals(true); + nameEdit->setText(CALCULATOR->convertToValidFunctionName(name.ascii()).c_str()); + nameEdit->blockSignals(false); + } +} + + +QalculateEditDataPropertyDialog::QalculateEditDataPropertyDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Property"), Ok | Cancel, Ok, true) { + + names_edit_dialog = NULL; + edited_property = NULL; + + setMainWidget(new QWidget(this)); + QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint()); + grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 0, 0); + nameEdit = new KLineEdit(mainWidget()); + grid->addWidget(nameEdit, 0, 1); + QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 1, 1, 0, 1); + namesLabel = new QLabel(mainWidget()); + namesLabel->setAlignment(Qt::AlignRight); + namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + hbox->addWidget(namesLabel); + namesButton = new QPushButton(i18n("Names Details"), mainWidget()); + hbox->addWidget(namesButton); + grid->addWidget(new QLabel(i18n("Descriptive name:"), mainWidget()), 2, 0); + titleEdit = new KLineEdit(mainWidget()); + grid->addWidget(titleEdit, 2, 1); + grid->addWidget(new QLabel(i18n("Description:"), mainWidget()), 3, 0); +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1 + descriptionEdit = new QTextEdit(mainWidget()); +#else + descriptionEdit = new KTextEdit(mainWidget()); +#endif + descriptionEdit->setTextFormat(QTextEdit::PlainText); + grid->addMultiCellWidget(descriptionEdit, 4, 4, 0, 1); + grid->addWidget(new QLabel(i18n("Value type:"), mainWidget()), 5, 0); + typeCombo = new KComboBox(mainWidget()); + typeCombo->setEditable(false); + typeCombo->insertItem(i18n("Text")); + typeCombo->insertItem(i18n("Number")); + typeCombo->insertItem(i18n("Expression")); + grid->addWidget(typeCombo, 5, 1); + hideButton = new QCheckBox(i18n("Hide"), mainWidget()); + grid->addWidget(hideButton, 6, 0); + //Use as a unique data set key + keyButton = new QCheckBox(i18n("Use as key"), mainWidget()); + grid->addWidget(keyButton, 6, 1); + approximateButton = new QCheckBox(i18n("Approximate value"), mainWidget()); + grid->addWidget(approximateButton, 7, 0); + caseButton = new QCheckBox(i18n("Case sensitive value"), mainWidget()); + grid->addWidget(caseButton, 7, 1); + bracketsButton = new QCheckBox(i18n("Value uses brackets"), mainWidget()); + grid->addWidget(bracketsButton, 8, 0); + grid->addWidget(new QLabel(i18n("Unit expression:"), mainWidget()), 9, 0); + unitEdit = new KLineEdit(mainWidget()); + grid->addWidget(unitEdit, 9, 1); + + connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames())); + +} + +QalculateEditDataPropertyDialog::~QalculateEditDataPropertyDialog() {} + +void QalculateEditDataPropertyDialog::slotOk() { + + string str = nameEdit->text().ascii(); + remove_blank_ends(str); + if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) { + //no name -- open dialog again + nameEdit->setFocus(); + KMessageBox::error(this, i18n("Empty name field")); + return; + } + DataProperty *dp = edited_property; + dp->setTitle(titleEdit->text().ascii()); + dp->setUnit(unitEdit->text().ascii()); + + dp->setHidden(hideButton->isChecked()); + dp->setKey(keyButton->isChecked()); + dp->setApproximate(approximateButton->isChecked()); + dp->setCaseSensitive(caseButton->isChecked()); + dp->setUsesBrackets(bracketsButton->isChecked()); + + dp->setDescription(descriptionEdit->text().ascii()); + + switch(typeCombo->currentItem()) { + case 0: { + dp->setPropertyType(PROPERTY_STRING); + break; + } + case 1: { + dp->setPropertyType(PROPERTY_NUMBER); + break; + } + case 2: { + dp->setPropertyType(PROPERTY_EXPRESSION); + break; + } + } + if(names_edit_dialog) { + names_edit_dialog->saveNames(dp, str.c_str()); + } else { + dp->setName(str, 1); + } + edited_property = dp; + accept(); + +} + +bool QalculateEditDataPropertyDialog::editDataProperty(DataProperty *dp, bool newdp) { + + nameEdit->setFocus(); + + if(names_edit_dialog) { + delete names_edit_dialog; + names_edit_dialog = NULL; + } + edited_property = dp; + if(!newdp) { + setCaption(i18n("Edit Property")); + } else { + setCaption(i18n("New Property")); + } + + actionButton(Ok)->setEnabled(true); + + nameEdit->setText(dp->getName().c_str()); + if(dp->countNames() > 1) { + QString str = "+ "; + for(size_t i = 2; i <= dp->countNames(); i++) { + if(i > 2) str += ", "; + str += dp->getName(i).c_str(); + } + namesLabel->setText(str); + } else { + namesLabel->clear(); + } + + titleEdit->setText(dp->title(false).c_str()); + unitEdit->setText(dp->getUnitString().c_str()); + + hideButton->setChecked(dp->isHidden()); + keyButton->setChecked(dp->isKey()); + approximateButton->setChecked(dp->isApproximate()); + caseButton->setChecked(dp->isCaseSensitive()); + bracketsButton->setChecked(dp->usesBrackets()); + + descriptionEdit->setText(dp->description().c_str()); + + switch(dp->propertyType()) { + case PROPERTY_STRING: { + typeCombo->setCurrentItem(0); + break; + } + case PROPERTY_NUMBER: { + typeCombo->setCurrentItem(1); + break; + } + case PROPERTY_EXPRESSION: { + typeCombo->setCurrentItem(2); + break; + } + } + + if(exec() == QDialog::Accepted) { + edited_property = NULL; + return true; + } + edited_property = NULL; + return false; +} + +void QalculateEditDataPropertyDialog::editNames() { + if(!names_edit_dialog) { + names_edit_dialog = new QalculateEditDataPropertyNamesDialog(this); + names_edit_dialog->setNames(edited_property, nameEdit->text(), false); + } else { + names_edit_dialog->setNames(edited_property, nameEdit->text(), true); + } + names_edit_dialog->exec(); + names_edit_dialog->setNamesLE(nameEdit, namesLabel); +} + + +QalculateEditDataPropertyNamesDialog::QalculateEditDataPropertyNamesDialog(QWidget *parent, const char *name) : KDialog(parent, name, true) { + + setCaption(i18n("Edit Names")); + + QVBoxLayout *layout = new QVBoxLayout(this, marginHint(), spacingHint()); + + namesView = new KListView(this); + namesView->addColumn(i18n("Name")); + namesView->addColumn(i18n("Reference")); + namesView->setColumnAlignment(1, Qt::AlignCenter); + namesView->setSorting(-1); + namesView->setItemsRenameable(true); + namesView->setItemsMovable(true); + layout->addWidget(namesView); + + QHBoxLayout *buttonLayout = new QHBoxLayout(layout, spacingHint()); + newButton = new QPushButton(i18n("New"), this); + buttonLayout->addWidget(newButton); + deleteButton = new QPushButton(i18n("Delete"), this); + deleteButton->setEnabled(false); + buttonLayout->addWidget(deleteButton); + buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + buttonClose = new KPushButton(KStdGuiItem::close(), this); + buttonClose->setAutoDefault(true); + buttonClose->setDefault(true); + buttonLayout->addWidget(buttonClose); + + connect(namesView, SIGNAL(selectionChanged()), this, SLOT(nameSelectionChanged())); + connect(buttonClose, SIGNAL(clicked()), this, SLOT(accept())); + connect(newButton, SIGNAL(clicked()), this, SLOT(newName())); + connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteName())); + connect(namesView, SIGNAL(clicked(QListViewItem*, const QPoint&, int)), this, SLOT(itemClicked(QListViewItem*, const QPoint&, int))); + +} + +QalculateEditDataPropertyNamesDialog::~QalculateEditDataPropertyNamesDialog() {} + +void QalculateEditDataPropertyNamesDialog::newName() { + ExpressionName name; + QListViewItem *i = new KListViewItem(namesView, namesView->lastChild(), "", i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No")); + namesView->setSelected(i, true); + qApp->processEvents(); + namesView->rename(i, 0); +} + +void QalculateEditDataPropertyNamesDialog::setNames(DataProperty *item, const QString &namestr, bool names_edited) { + + if(!names_edited) { + deleteButton->setEnabled(false); + namesView->clear(); + } + if(!names_edited && item && item->countNames() > 0) { + QListViewItem *i_prev = NULL; + for(size_t index = 1; index <= item->countNames(); index++) { + QListViewItem *i = new KListViewItem(namesView, i_prev); + i_prev = i; + if(item->nameIsReference(index)) + i->setText(1, i18n("Yes")); + else + i->setText(1, i18n("No")); + if(index == 1 && !namestr.isEmpty()) { + i->setText(0, namestr); + } else { + i->setText(0, item->getName(index).c_str()); + } + } + } else if(!namestr.isEmpty()) { + if(names_edited) { + QListViewItemIterator it(namesView); + if(it.current()) + it.current()->setText(0, namestr); + } else { + new KListViewItem(namesView, namestr, i18n("No")); + } + } +} +void QalculateEditDataPropertyNamesDialog::saveNames(DataProperty *item, const QString &str) { + item->clearNames(); + QListViewItemIterator it(namesView); + if(it.current()) { + bool b = false; + while(it.current()) { + bool ref = (it.current()->text(1) == i18n("Yes")); + if(b || str.isEmpty()) + item->addName(it.current()->text(0).ascii(), ref); + else + item->addName(str.ascii(), ref); + ++it; + b = true; + } + } else { + item->addName(str.ascii()); + } +} +void QalculateEditDataPropertyNamesDialog::setNamesLE(QLineEdit *entry, QLabel *label) { + int index = 0; + QString str; + QListViewItemIterator it(namesView); + while(it.current()) { + if(index == 0) { + entry->setText(it.current()->text(0)); + } else { + if(index == 1) { + str = "+ "; + } else { + str += ", "; + } + str += it.current()->text(0); + } + ++it; + index++; + } + label->setText(str); +} +bool QalculateEditDataPropertyNamesDialog::isEmpty() { + return namesView->childCount() <= 0; +} + +void QalculateEditDataPropertyNamesDialog::deleteName() { + namesView->removeItem(namesView->selectedItem()); +} + +void QalculateEditDataPropertyNamesDialog::itemClicked(QListViewItem *i, const QPoint &, int c) { + if(i && c > 0) { + if(i->text(c) == i18n("Yes")) + i->setText(c, i18n("No")); + else + i->setText(c, i18n("Yes")); + } +} + +void QalculateEditDataPropertyNamesDialog::nameSelectionChanged() { + deleteButton->setEnabled(namesView->selectedItem() != NULL); +} + + +#include "qalculateeditdatasetdialog.moc" + diff --git a/src/qalculateeditdatasetdialog.h b/src/qalculateeditdatasetdialog.h new file mode 100644 index 0000000..2c27b65 --- /dev/null +++ b/src/qalculateeditdatasetdialog.h @@ -0,0 +1,145 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEEDITDATASETDIALOG_H +#define QALCULATEEDITDATASETDIALOG_H + +#include +#include +#include + +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 propertiesItems; + QValueVector tmp_props; + QValueVector tmp_props_orig; + +public slots: + + void propertySelectionChanged(); + void editNames(); + void newProperty(); + void editProperty(); + void deleteProperty(); + void nameChanged(const QString&); + +protected slots: + + void slotOk(); + +}; + +class QalculateEditDataPropertyDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateEditDataPropertyDialog(QWidget *parent = 0, const char *name = 0); + ~QalculateEditDataPropertyDialog(); + + bool editDataProperty(DataProperty *dp, bool newdp = false); + + QalculateEditDataPropertyNamesDialog *names_edit_dialog; + DataProperty *edited_property; + KComboBox *typeCombo; + KLineEdit *nameEdit, *titleEdit, *unitEdit; + QLabel *namesLabel; + QCheckBox *hideButton, *keyButton, *approximateButton, *caseButton, *bracketsButton; + QPushButton *namesButton; + QTextEdit *descriptionEdit; + +public slots: + + void editNames(); + +protected slots: + + void slotOk(); + +}; + +class QalculateEditDataPropertyNamesDialog : public KDialog { + + Q_OBJECT + +public: + + QalculateEditDataPropertyNamesDialog(QWidget *parent = 0, const char *name = 0); + ~QalculateEditDataPropertyNamesDialog(); + + void saveNames(DataProperty *item, const QString &str = QString::null); + void setNames(DataProperty *item = NULL, const QString &namestr = QString::null, bool names_edited = false); + bool isEmpty(); + void setNamesLE(QLineEdit *entry, QLabel *label); + + KListView* namesView; + QPushButton* newButton; + QPushButton* deleteButton; + QPushButton* buttonClose; + int i_type; + +public slots: + + void itemClicked(QListViewItem*, const QPoint&, int); + void newName(); + void deleteName(); + void nameSelectionChanged(); + +}; + +#endif diff --git a/src/qalculateeditfunctiondialog.cpp b/src/qalculateeditfunctiondialog.cpp new file mode 100644 index 0000000..f82b0cb --- /dev/null +++ b/src/qalculateeditfunctiondialog.cpp @@ -0,0 +1,799 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateeditfunctiondialog.h" +#include "qalculate_kde_utils.h" +#include "qalculateeditnamesdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1 +#include +#else +#include +#endif +#include +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 +#include +#else +#include +#endif +#include +#include +#include + +extern PrintOptions printops; +extern EvaluationOptions evalops; +extern tree_struct function_cats; + +QalculateEditFunctionDialog::QalculateEditFunctionDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Function"), Ok | Cancel | Help, Ok, false) { + + names_edit_dialog = NULL; + subfunctions_edit_dialog = NULL; + edited_function = NULL; + argument_edit_dialog = NULL; + +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + tabs = new QTabWidget(this); +#else + tabs = new KTabWidget(this); +#endif + setMainWidget(tabs); + QWidget *page1 = new QWidget(this); + QWidget *page2 = new QWidget(this); + tabs->addTab(page1, i18n("General")); + tabs->addTab(page2, i18n("Function")); + QGridLayout *grid = new QGridLayout(page1, 1, 1, spacingHint()); + QVBoxLayout *vbox = new QVBoxLayout(page2, spacingHint()); + grid->addWidget(new QLabel(i18n("Name:"), page1), 0, 0); + nameEdit = new KLineEdit(page1); + grid->addWidget(nameEdit, 0, 1); + QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 1, 1, 0, 1); + namesLabel = new QLabel(page1); + namesLabel->setAlignment(Qt::AlignRight); + namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + hbox->addWidget(namesLabel); + namesButton = new QPushButton(i18n("Names Details"), page1); + hbox->addWidget(namesButton); + grid->addWidget(new QLabel(i18n("Category:"), page1), 2, 0); + categoryCombo = new KComboBox(page1); + categoryCombo->setMaximumWidth(250); + categoryCombo->setEditable(true); + grid->addWidget(categoryCombo, 2, 1); + grid->addWidget(new QLabel(i18n("Descriptive name:"), page1), 3, 0); + titleEdit = new KLineEdit(page1); + grid->addWidget(titleEdit, 3, 1); + hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 4, 4, 0, 1); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + hideButton = new QCheckBox(i18n("Hide function"), page1); + hbox->addWidget(hideButton); + grid->addWidget(new QLabel(i18n("Description:"), page1), 5, 0); +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1 + descriptionEdit = new QTextEdit(page1); +#else + descriptionEdit = new KTextEdit(page1); +#endif + descriptionEdit->setTextFormat(QTextEdit::PlainText); + grid->addMultiCellWidget(descriptionEdit, 6, 6, 0, 1); + vbox->addWidget(new QLabel(i18n("Expression:"), page2)); +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 1 + expressionEdit = new QTextEdit(page2); +#else + expressionEdit = new KTextEdit(page2); +#endif + expressionEdit->setTextFormat(QTextEdit::PlainText); + vbox->addWidget(expressionEdit); + hbox = new QHBoxLayout(vbox, spacingHint()); + hbox->addWidget(new QLabel(i18n("Condition:"), page2)); + conditionEdit = new KLineEdit(page2); + hbox->addWidget(conditionEdit); + hbox = new QHBoxLayout(vbox, spacingHint()); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + subFunctionsButton = new QPushButton(i18n("Sub-Functions"), page2); + hbox->addWidget(subFunctionsButton); + vbox->addWidget(new QLabel(i18n("Arguments:"), page2)); + argumentsView = new KListView(page2); + argumentsView->addColumn(i18n("Name")); + argumentsView->addColumn(i18n("Type")); + argumentsView->setSorting(-1); + argumentsView->setRootIsDecorated(false); + argumentsView->setItemsRenameable(true); + argumentsView->setItemsMovable(false); + vbox->addWidget(argumentsView); + hbox = new QHBoxLayout(vbox, spacingHint()); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + newArgumentButton = new QPushButton(i18n("New"), page2); + hbox->addWidget(newArgumentButton); + editArgumentButton = new QPushButton(i18n("Edit"), page2); + hbox->addWidget(editArgumentButton); + deleteArgumentButton = new QPushButton(i18n("Delete"), page2); + hbox->addWidget(deleteArgumentButton); + + connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames())); + connect(subFunctionsButton, SIGNAL(clicked()), this, SLOT(editSubFunctions())); + connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&))); + connect(newArgumentButton, SIGNAL(clicked()), this, SLOT(newArgument())); + connect(editArgumentButton, SIGNAL(clicked()), this, SLOT(editArgument())); + connect(deleteArgumentButton, SIGNAL(clicked()), this, SLOT(deleteArgument())); + connect(argumentsView, SIGNAL(itemRenamed(QListViewItem*, const QString&, int)), this, SLOT(argumentRenamed(QListViewItem*, const QString&, int))); + connect(argumentsView, SIGNAL(selectionChanged()), this, SLOT(argumentSelectionChanged())); + +} + +QalculateEditFunctionDialog::~QalculateEditFunctionDialog() {} + + +void QalculateEditFunctionDialog::slotHelp() { + KApplication::kApplication()->invokeHelp("qalculate-function-creation"); +} + +void QalculateEditFunctionDialog::argumentSelectionChanged() { + QListViewItem *i = argumentsView->selectedItem(); + if(i == NULL || (edited_function && edited_function->isBuiltin()) || argumentsItems[i]->type() > ARGUMENT_TYPE_ANGLE) { + editArgumentButton->setEnabled(false); + deleteArgumentButton->setEnabled(false); + } else { + editArgumentButton->setEnabled(true); + deleteArgumentButton->setEnabled(true); + } +} +void QalculateEditFunctionDialog::argumentRenamed(QListViewItem *i, const QString &str, int col) { + if(!i || col != 0) return; + if(col == 0) { + if(!argumentsItemsEdited[i]) { + argumentsItems[i] = argumentsItems[i]->copy(); + argumentsItemsEdited[i] = true; + } + argumentsItems[i]->setName(str.ascii()); + } +} + +void QalculateEditFunctionDialog::slotOk() { + + string str = nameEdit->text().ascii(); + remove_blank_ends(str); + string str2 = CALCULATOR->unlocalizeExpression(expressionEdit->text().ascii(), evalops.parse_options); + remove_blank_ends(str2); + gsub("\n", " ", str2); + if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) { + //no name -- open dialog again + tabs->setCurrentPage(0); + nameEdit->setFocus(); + KMessageBox::error(this, i18n("Empty name field")); + return; + } + if(!(edited_function && edited_function->isBuiltin()) && str2.empty()) { + //no expression/relation -- open dialog again + tabs->setCurrentPage(1); + expressionEdit->setFocus(); + KMessageBox::error(this, i18n("Empty expression field")); + return; + } + //function with the same name exists -- overwrite or open dialog again + if((!edited_function || !edited_function->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->functionNameTaken(str, edited_function) && KMessageBox::questionYesNo(this, i18n("A function with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) { + tabs->setCurrentPage(0); + nameEdit->setFocus(); + return; + } + + MathFunction *f = edited_function; + + bool add_func = false; + if(f) { + f->setLocal(true); + //edited an existing function + f->setCategory(categoryCombo->lineEdit()->text().ascii()); + f->setTitle(titleEdit->text().ascii()); + f->setDescription(descriptionEdit->text().ascii()); + } else { + //new function + f = new UserFunction(categoryCombo->lineEdit()->text().ascii(), "", "", true, -1, titleEdit->text().ascii(), descriptionEdit->text().ascii()); + add_func = true; + } + f->setCondition(CALCULATOR->unlocalizeExpression(conditionEdit->text().ascii(), evalops.parse_options)); + size_t index = 1; + QListViewItemIterator it(argumentsView); + while(it.current()) { + if(argumentsItemsEdited[it.current()]) { + if(f->isBuiltin() && f->getArgumentDefinition(index)) { + f->getArgumentDefinition(index)->setName(argumentsItems[it.current()]->name()); + delete argumentsItems[it.current()]; + } else { + f->setArgumentDefinition(index, argumentsItems[it.current()]); + } + } + ++it; + index++; + } + if(!f->isBuiltin()) { + for(; index <= f->lastArgumentDefinitionIndex(); index++) { + f->setArgumentDefinition(index, NULL); + } + } + argumentsItemsEdited.clear(); + argumentsItems.clear(); + f->setHidden(hideButton->isChecked()); + if(!f->isBuiltin()) { + if(names_edit_dialog) { + names_edit_dialog->saveNames(f, str.c_str()); + } else { + if(f->countNames() == 0) { + ExpressionName ename(str); + ename.reference = true; + f->setName(ename, 1); + } else { + f->setName(str, 1); + } + } + if(subfunctions_edit_dialog) { + subfunctions_edit_dialog->saveSubFunctions((UserFunction*) f); + } + ((UserFunction*) f)->setFormula(str2); + } + if(add_func) { + CALCULATOR->addFunction(f); + } + edited_function = f; + + accept(); + +} + +MathFunction *QalculateEditFunctionDialog::editFunction(QString category, MathFunction *f) { + + nameEdit->setFocus(); + + tabs->setCurrentPage(0); + if(names_edit_dialog) { + delete names_edit_dialog; + names_edit_dialog = NULL; + } + if(subfunctions_edit_dialog) { + delete subfunctions_edit_dialog; + subfunctions_edit_dialog = NULL; + } + edited_function = f; + if(f) { + if(f->isLocal()) + setCaption(i18n("Edit Function")); + else + setCaption(i18n("Edit Function (global)")); + } else { + setCaption(i18n("New Function")); + } + + QString catstr; + categoryCombo->clear(); + tree_struct *item, *item2; + function_cats.it = function_cats.items.begin(); + if(function_cats.it != function_cats.items.end()) { + item = &*function_cats.it; + ++function_cats.it; + item->it = item->items.begin(); + } else { + item = NULL; + } + + catstr = ""; + while(item) { + if(!catstr.isEmpty()) catstr += "/"; + catstr += item->item.c_str(); + categoryCombo->insertItem(catstr); + while(item && item->it == item->items.end()) { + int str_i = catstr.findRev("/"); + if(str_i < 0) { + catstr = ""; + } else { + catstr.truncate(str_i); + } + item = item->parent; + } + if(item) { + item2 = &*item->it; + ++item->it; + item = item2; + item->it = item->items.begin(); + } + } + + //clear entries + nameEdit->clear(); + namesLabel->clear(); + conditionEdit->clear(); + nameEdit->setReadOnly(f && f->isBuiltin()); + expressionEdit->setEnabled(!f || !f->isBuiltin()); + categoryCombo->lineEdit()->setText(category); + titleEdit->clear(); + descriptionEdit->clear(); + expressionEdit->clear(); + hideButton->setChecked(false); + actionButton(Ok)->setEnabled(true); + subFunctionsButton->setEnabled(!f || !f->isBuiltin()); + conditionEdit->setReadOnly(f && f->isBuiltin()); + newArgumentButton->setEnabled(!f || !f->isBuiltin()); + if(f) { + //fill in original paramaters + set_name_label_and_entry(f, nameEdit, namesLabel); + if(!f->isBuiltin()) { + expressionEdit->setText(CALCULATOR->localizeExpression(((UserFunction*) f)->formula()).c_str()); + } + categoryCombo->lineEdit()->setText(f->category().c_str()); + titleEdit->setText(f->title(false).c_str()); + conditionEdit->setText(CALCULATOR->localizeExpression(f->condition()).c_str()); + hideButton->setChecked(f->isHidden()); + descriptionEdit->setText(f->description().c_str()); + + } + argumentsView->clear(); + argumentsItems.clear(); + argumentsItemsEdited.clear(); + editArgumentButton->setEnabled(false); + deleteArgumentButton->setEnabled(false); + Argument defarg; + if(f) { + Argument *arg; + int args = f->maxargs(); + if(args < 0) { + args = f->minargs() + 1; + } + QString str, str2; + QListViewItem *i_prev = NULL; + for(int i = 1; i <= args; i++) { + arg = f->getArgumentDefinition(i); + if(arg) { + arg = arg->copy(); + str = arg->printlong().c_str(); + str2 = arg->name().c_str(); + } else { + arg = &defarg; + str = defarg.printlong().c_str(); + str2 = ""; + } + QListViewItem *i = new KListViewItem(argumentsView, i_prev, str2, str); + i_prev = i; + argumentsItems[i] = arg; + argumentsItemsEdited[i] = false; + } + } + argumentsView->setResizeMode(KListView::AllColumns); + + if(exec() == QDialog::Accepted) { + f = edited_function; + edited_function = NULL; + return f; + } + QListViewItemIterator it(argumentsView); + while(it.current()) { + if(argumentsItemsEdited[it.current()]) { + delete argumentsItems[it.current()]; + } + ++it; + } + argumentsItemsEdited.clear(); + argumentsItems.clear(); + edited_function = NULL; + return NULL; +} + +void QalculateEditFunctionDialog::editNames() { + if(!names_edit_dialog) { + names_edit_dialog = new QalculateEditNamesDialog(TYPE_FUNCTION, this); + names_edit_dialog->setNames(edited_function, nameEdit->text(), false); + } else { + names_edit_dialog->setNames(edited_function, nameEdit->text(), true); + } + names_edit_dialog->exec(); + names_edit_dialog->setNamesLE(nameEdit, namesLabel); +} +void QalculateEditFunctionDialog::newArgument() { + if(!argument_edit_dialog) { + argument_edit_dialog = new QalculateEditArgumentDialog(this); + } + Argument *arg = argument_edit_dialog->editArgument(); + if(arg) { + QListViewItem *i = new KListViewItem(argumentsView, argumentsView->lastChild(), arg->name().c_str(), arg->printlong().c_str()); + argumentsItems[i] = arg; + argumentsItemsEdited[i] = true; + } +} +void QalculateEditFunctionDialog::editArgument() { + QListViewItem *i = argumentsView->selectedItem(); + if(i == NULL) return; + if(!argument_edit_dialog) { + argument_edit_dialog = new QalculateEditArgumentDialog(this); + } + Argument *arg = argument_edit_dialog->editArgument(argumentsItems[i]); + if(arg) { + if(argumentsItemsEdited[i]) { + delete argumentsItems[i]; + } + argumentsItemsEdited[i] = true; + argumentsItems[i] = arg; + i->setText(0, arg->name().c_str()); + i->setText(1, arg->printlong().c_str()); + } +} +void QalculateEditFunctionDialog::deleteArgument() { + QListViewItem *i = argumentsView->selectedItem(); + if(i == NULL) return; + if(argumentsItemsEdited[i]) { + delete argumentsItems[i]; + } + argumentsItemsEdited.erase(i); + argumentsItems.erase(i); + argumentsView->removeItem(i); +} +void QalculateEditFunctionDialog::editSubFunctions() { + if(edited_function && edited_function->isBuiltin()) return; + if(!subfunctions_edit_dialog) { + subfunctions_edit_dialog = new QalculateEditSubFunctionsDialog(this); + subfunctions_edit_dialog->setSubFunctions((UserFunction*) edited_function, false); + } else { + subfunctions_edit_dialog->setSubFunctions((UserFunction*) edited_function, true); + } + subfunctions_edit_dialog->exec(); +} + +void QalculateEditFunctionDialog::nameChanged(const QString &name) { + if(name.isNull()) return; + if(!CALCULATOR->functionNameIsValid(name.ascii())) { + nameEdit->blockSignals(true); + nameEdit->setText(CALCULATOR->convertToValidFunctionName(name.ascii()).c_str()); + nameEdit->blockSignals(false); + } +} + +QalculateEditSubFunctionsDialog::QalculateEditSubFunctionsDialog(QWidget *parent, const char *name) : KDialog(parent, name, true) { + + setCaption(i18n("Sub-Functions")); + + QVBoxLayout *layout = new QVBoxLayout(this, marginHint(), spacingHint()); + + subFunctionsView = new KListView(this); + subFunctionsView->addColumn(i18n("Reference")); + subFunctionsView->addColumn(i18n("Expression")); + subFunctionsView->addColumn(i18n("Precalculate")); + subFunctionsView->setSorting(-1); + subFunctionsView->setItemsRenameable(true); + subFunctionsView->setRenameable(0, false); + subFunctionsView->setRenameable(1, true); + subFunctionsView->setItemsMovable(false); + layout->addWidget(subFunctionsView); + + QHBoxLayout *buttonLayout = new QHBoxLayout(layout, spacingHint()); + newButton = new QPushButton(i18n("New"), this); + buttonLayout->addWidget(newButton); + deleteButton = new QPushButton(i18n("Delete"), this); + deleteButton->setEnabled(false); + buttonLayout->addWidget(deleteButton); + buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + buttonClose = new KPushButton(KStdGuiItem::close(), this); + buttonClose->setAutoDefault(true); + buttonClose->setDefault(true); + buttonLayout->addWidget(buttonClose); + + connect(subFunctionsView, SIGNAL(selectionChanged()), this, SLOT(selectionChanged())); + connect(buttonClose, SIGNAL(clicked()), this, SLOT(accept())); + connect(newButton, SIGNAL(clicked()), this, SLOT(newSubFunction())); + connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteSubFunction())); + connect(subFunctionsView, SIGNAL(clicked(QListViewItem*, const QPoint&, int)), this, SLOT(itemClicked(QListViewItem*, const QPoint&, int))); +} + +QalculateEditSubFunctionsDialog::~QalculateEditSubFunctionsDialog() {} + +void QalculateEditSubFunctionsDialog::newSubFunction() { + ExpressionName name; + QString str = "\\"; + str += QString::number(subFunctionsView->childCount() + 1); + QListViewItem *i = new KListViewItem(subFunctionsView, subFunctionsView->lastChild(), str, "", i18n("Yes")); + subFunctionsView->setSelected(i, true); + qApp->processEvents(); + subFunctionsView->rename(i, 1); +} + +void QalculateEditSubFunctionsDialog::setSubFunctions(UserFunction *f, bool edited) { + if(!edited) { + deleteButton->setEnabled(false); + subFunctionsView->clear(); + } + if(!edited && f && f->countSubfunctions() > 0) { + QListViewItem *i_prev = NULL; + for(size_t index = 1; index <= f->countSubfunctions(); index++) { + QListViewItem *i = new KListViewItem(subFunctionsView, i_prev); + i_prev = i; + QString str = "\\"; + str += QString::number(index); + i->setText(0, str); + i->setText(1, f->getSubfunction(index).c_str()); + if(f->subfunctionPrecalculated(index)) i->setText(2, i18n("Yes")); + else i->setText(2, i18n("No")); + } + } +} +void QalculateEditSubFunctionsDialog::saveSubFunctions(UserFunction *f) { + f->clearSubfunctions(); + QListViewItemIterator it(subFunctionsView); + while(it.current()) { + f->addSubfunction(it.current()->text(1).ascii(), it.current()->text(2) == i18n("Yes")); + ++it; + } +} +bool QalculateEditSubFunctionsDialog::isEmpty() { + return subFunctionsView->childCount() <= 0; +} + +void QalculateEditSubFunctionsDialog::deleteSubFunction() { + subFunctionsView->removeItem(subFunctionsView->selectedItem()); + QListViewItemIterator it(subFunctionsView); + int index = 1; + while(it.current()) { + QString str = "\\"; + str += QString::number(index); + it.current()->setText(0, str); + ++it; + index++; + } +} + +void QalculateEditSubFunctionsDialog::itemClicked(QListViewItem *i, const QPoint &, int c) { + if(i && c == 2) { + if(i->text(c) == i18n("Yes")) + i->setText(c, i18n("No")); + else + i->setText(c, i18n("Yes")); + } +} + +void QalculateEditSubFunctionsDialog::selectionChanged() { + deleteButton->setEnabled(subFunctionsView->selectedItem() != NULL); +} + +QalculateEditArgumentDialog::QalculateEditArgumentDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Argument"), Ok | Cancel, Ok, true) { + + setMainWidget(new QWidget(this)); + QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint()); + grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 0, 0); + nameEdit = new KLineEdit(mainWidget()); + grid->addWidget(nameEdit, 0, 1); + grid->addWidget(new QLabel(i18n("Type:"), mainWidget()), 1, 0); + typeCombo = new KComboBox(mainWidget()); + typeCombo->setEditable(false); + typeCombo->insertItem(i18n("Free")); + typeCombo->insertItem(i18n("Number")); + typeCombo->insertItem(i18n("Integer")); + typeCombo->insertItem(i18n("Symbol")); + typeCombo->insertItem(i18n("Text")); + typeCombo->insertItem(i18n("Date")); + typeCombo->insertItem(i18n("Vector")); + typeCombo->insertItem(i18n("Matrix")); + typeCombo->insertItem(i18n("Boolean")); + typeCombo->insertItem(i18n("Object")); + typeCombo->insertItem(i18n("Function")); + typeCombo->insertItem(i18n("Unit")); + typeCombo->insertItem(i18n("Variable")); + typeCombo->insertItem(i18n("File")); + typeCombo->insertItem(i18n("Angle")); + grid->addWidget(typeCombo, 1, 1); + testButton = new QCheckBox(i18n("Enable rules and type test"), mainWidget()); + grid->addMultiCellWidget(testButton, 2, 2, 0, 1); + conditionButton = new QCheckBox(i18n("Custom condition:"), mainWidget()); + grid->addWidget(conditionButton, 3, 0); + conditionEdit = new KLineEdit(mainWidget()); + grid->addWidget(conditionEdit, 3, 1); + matrixButton = new QCheckBox(i18n("Allow matrix"), mainWidget()); + grid->addMultiCellWidget(matrixButton, 4, 4, 0, 1); + zeroButton = new QCheckBox(i18n("Forbid zero"), mainWidget()); + grid->addMultiCellWidget(zeroButton, 5, 5, 0, 1); + complexButton = new QCheckBox(i18n("Allow complex"), mainWidget()); + grid->addMultiCellWidget(complexButton, 6, 6, 0, 1); + minButton = new QCheckBox(i18n("Min:"), mainWidget()); + grid->addWidget(minButton, 7, 0); + minEdit = new KLineEdit(mainWidget()); + grid->addWidget(minEdit, 7, 1); + QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 8, 8, 0, 1); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + minIncludeEqualsButton = new QCheckBox(i18n("Include equals"), mainWidget()); + hbox->addWidget(minIncludeEqualsButton); + maxButton = new QCheckBox(i18n("Max:"), mainWidget()); + grid->addWidget(maxButton, 9, 0); + maxEdit = new KLineEdit(mainWidget()); + grid->addWidget(maxEdit, 9, 1); + hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 10, 10, 0, 1); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + maxIncludeEqualsButton = new QCheckBox(i18n("Include equals"), mainWidget()); + hbox->addWidget(maxIncludeEqualsButton); + + connect(conditionButton, SIGNAL(toggled(bool)), conditionEdit, SLOT(setEnabled(bool))); + connect(minButton, SIGNAL(toggled(bool)), this, SLOT(minEnabled(bool))); + connect(maxButton, SIGNAL(toggled(bool)), this, SLOT(maxEnabled(bool))); + connect(typeCombo, SIGNAL(activated(int)), this, SLOT(typeChanged(int))); + +} + +QalculateEditArgumentDialog::~QalculateEditArgumentDialog() {} + +void QalculateEditArgumentDialog::typeChanged(int i) { + maxButton->setEnabled(i == 1 || i == 2); + maxEdit->setEnabled(maxButton->isChecked() && (i == 1 || i == 2)); + maxIncludeEqualsButton->setEnabled(maxButton->isChecked() && i == 1); + maxIncludeEqualsButton->setChecked(i == 1 || i == 2); + minButton->setEnabled(i == 1 || i == 2); + minEdit->setEnabled(maxButton->isChecked() && (i == 1 || i == 2)); + minIncludeEqualsButton->setEnabled(minButton->isChecked() && i == 1); + minIncludeEqualsButton->setChecked(i == 1 || i == 2); + matrixButton->setEnabled(i != 7 && i != 0); + matrixButton->setChecked(i == 7 || i == 0); + complexButton->setEnabled(i == 1); + complexButton->setChecked(i == 1); +} +void QalculateEditArgumentDialog::maxEnabled(bool b) { + maxEdit->setEnabled(b); + if(typeCombo->currentItem() == 2) { + maxIncludeEqualsButton->setEnabled(b); + } +} +void QalculateEditArgumentDialog::minEnabled(bool b) { + minEdit->setEnabled(b); + if(typeCombo->currentItem() == 2) { + minIncludeEqualsButton->setEnabled(b); + } +} + +Argument *QalculateEditArgumentDialog::editArgument(Argument *arg) { + + if(arg) { + setCaption(i18n("Edit Argument")); + } else { + setCaption(i18n("New Argument")); + } + + nameEdit->setFocus(); + + typeCombo->setCurrentItem(0); + conditionEdit->clear(); + conditionButton->setChecked(false); + nameEdit->clear(); + maxEdit->setText("0"); + minEdit->setText("0"); + testButton->setChecked(true); + zeroButton->setChecked(false); + matrixButton->setChecked(false); + complexButton->setChecked(false); + PrintOptions po; + po.number_fraction_format = FRACTION_DECIMAL_EXACT; + if(arg) { + switch(arg->type()) { + case ARGUMENT_TYPE_NUMBER: { + typeCombo->setCurrentItem(1); + NumberArgument *farg = (NumberArgument*) arg; + minButton->setChecked(farg->min() != NULL); + minIncludeEqualsButton->setChecked(farg->includeEqualsMin()); + if(farg->min()) minEdit->setText(farg->min()->print(po).c_str()); + maxButton->setChecked(farg->max() != NULL); + maxIncludeEqualsButton->setChecked(farg->includeEqualsMax()); + if(farg->max()) maxEdit->setText(farg->max()->print(po).c_str()); + complexButton->setChecked(farg->complexAllowed()); + break; + } + case ARGUMENT_TYPE_INTEGER: { + typeCombo->setCurrentItem(2); + IntegerArgument *iarg = (IntegerArgument*) arg; + minButton->setChecked(iarg->min() != NULL); + if(iarg->min()) minEdit->setText(iarg->min()->print(po).c_str()); + maxButton->setChecked(iarg->max() != NULL); + if(iarg->max()) maxEdit->setText(iarg->max()->print(po).c_str()); + break; + } + case ARGUMENT_TYPE_TEXT: {typeCombo->setCurrentItem(4); break;} + case ARGUMENT_TYPE_SYMBOLIC: {typeCombo->setCurrentItem(3); break;} + case ARGUMENT_TYPE_DATE: {typeCombo->setCurrentItem(5); break;} + case ARGUMENT_TYPE_VECTOR: {typeCombo->setCurrentItem(6); break;} + case ARGUMENT_TYPE_MATRIX: {typeCombo->setCurrentItem(7); break;} + case ARGUMENT_TYPE_EXPRESSION_ITEM: {typeCombo->setCurrentItem(9); break;} + case ARGUMENT_TYPE_FUNCTION: {typeCombo->setCurrentItem(10); break;} + case ARGUMENT_TYPE_UNIT: {typeCombo->setCurrentItem(11); break;} + case ARGUMENT_TYPE_VARIABLE: {typeCombo->setCurrentItem(12); break;} + case ARGUMENT_TYPE_FILE: {typeCombo->setCurrentItem(13); break;} + case ARGUMENT_TYPE_BOOLEAN: {typeCombo->setCurrentItem(8); break;} + case ARGUMENT_TYPE_ANGLE: {typeCombo->setCurrentItem(14); break;} + } + nameEdit->setText(arg->name().c_str()); + matrixButton->setChecked(arg->matrixAllowed()); + zeroButton->setChecked(arg->zeroForbidden()); + testButton->setChecked(arg->tests()); + if(!arg->getCustomCondition().empty()) { + conditionButton->setChecked(true); + conditionEdit->setText(arg->getCustomCondition().c_str()); + } + } + typeChanged(typeCombo->currentItem()); + + if(exec() == QDialog::Accepted) { + switch(typeCombo->currentItem()) { + case 1: { + arg = new NumberArgument(); + if(minButton->isChecked()) { + Number nr(minEdit->text().ascii()); + ((NumberArgument*) arg)->setMin(&nr); + } + ((NumberArgument*) arg)->setIncludeEqualsMin(minIncludeEqualsButton->isChecked()); + if(maxButton->isChecked()) { + Number nr(maxEdit->text().ascii()); + ((NumberArgument*) arg)->setMax(&nr); + } + ((NumberArgument*) arg)->setIncludeEqualsMax(maxIncludeEqualsButton->isChecked()); + break; + } + case 2: { + arg = new IntegerArgument(); + if(minButton->isChecked()) { + Number nr(minEdit->text().ascii()); + ((IntegerArgument*) arg)->setMin(&nr); + } + if(maxButton->isChecked()) { + Number nr(maxEdit->text().ascii()); + ((IntegerArgument*) arg)->setMax(&nr); + } + break; + } + case 3: {arg = new SymbolicArgument(); break;} + case 4: {arg = new TextArgument(); break;} + case 5: {arg = new DateArgument(); break;} + case 6: {arg = new VectorArgument(); break;} + case 7: {arg = new MatrixArgument(); break;} + case 8: {arg = new BooleanArgument(); break;} + case 9: {arg = new ExpressionItemArgument(); break;} + case 10: {arg = new FunctionArgument(); break;} + case 11: {arg = new UnitArgument(); break;} + case 12: {arg = new VariableArgument(); break;} + case 13: {arg = new FileArgument(); break;} + case 14: {arg = new AngleArgument(); break;} + default: {arg = new Argument(); break;} + } + arg->setName(nameEdit->text().ascii()); + arg->setZeroForbidden(zeroButton->isChecked()); + arg->setTests(testButton->isChecked()); + if(conditionButton->isChecked()) { + arg->setCustomCondition(conditionEdit->text().ascii()); + } else { + arg->setCustomCondition(""); + } + if(arg->type() != ARGUMENT_TYPE_FREE && arg->type() != ARGUMENT_TYPE_MATRIX) arg->setMatrixAllowed(matrixButton->isChecked()); + return arg; + } + return NULL; + +} + +#include "qalculateeditfunctiondialog.moc" + diff --git a/src/qalculateeditfunctiondialog.h b/src/qalculateeditfunctiondialog.h new file mode 100644 index 0000000..ecd322d --- /dev/null +++ b/src/qalculateeditfunctiondialog.h @@ -0,0 +1,140 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEEDITFUNCTIONDIALOG_H +#define QALCULATEEDITFUNCTIONDIALOG_H + +#include +#include + +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 argumentsItems; + QMap argumentsItemsEdited; + +public slots: + + void argumentSelectionChanged(); + void argumentRenamed(QListViewItem*, const QString&, int); + void editNames(); + void newArgument(); + void editArgument(); + void deleteArgument(); + void editSubFunctions(); + void nameChanged(const QString&); + +protected slots: + + void slotHelp(); + void slotOk(); + +}; + +class QalculateEditSubFunctionsDialog : public KDialog { + + Q_OBJECT + +public: + + QalculateEditSubFunctionsDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateEditSubFunctionsDialog(); + + void saveSubFunctions(UserFunction *f); + void setSubFunctions(UserFunction *f = NULL, bool edited = false); + bool isEmpty(); + + KListView* subFunctionsView; + QPushButton* newButton; + QPushButton* deleteButton; + QPushButton* buttonClose; + +public slots: + + void itemClicked(QListViewItem*, const QPoint&, int); + void newSubFunction(); + void deleteSubFunction(); + void selectionChanged(); + +}; + +class QalculateEditArgumentDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateEditArgumentDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateEditArgumentDialog(); + + Argument *editArgument(Argument *arg = NULL); + + KComboBox *typeCombo; + KLineEdit *nameEdit, *conditionEdit, *maxEdit, *minEdit; + QCheckBox *conditionButton, *matrixButton, *zeroButton, *complexButton, *maxButton, *minButton, *maxIncludeEqualsButton, *minIncludeEqualsButton, *testButton; + +public slots: + + void maxEnabled(bool); + void minEnabled(bool); + void typeChanged(int); + +}; + + +#endif diff --git a/src/qalculateeditmatrixvectordialog.cpp b/src/qalculateeditmatrixvectordialog.cpp new file mode 100644 index 0000000..1dccb03 --- /dev/null +++ b/src/qalculateeditmatrixvectordialog.cpp @@ -0,0 +1,491 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateeditmatrixvectordialog.h" +#include "qalculate_kde_utils.h" +#include "qalculateeditnamesdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern PrintOptions printops; +extern EvaluationOptions evalops; +extern tree_struct variable_cats; + +class QalculateEditMatrixVectorTableItem : public QTableItem { + + public: + + QalculateEditMatrixVectorTableItem(QTable *table); + QalculateEditMatrixVectorTableItem(QTable *table, const QString & text); + + int alignment() const; + +}; + +class QalculateEditMatrixTable : public QTable { + + public: + + QalculateEditMatrixTable(QWidget *parent = 0, const char *name = 0) : QTable(parent, name) {} + QalculateEditMatrixTable(int numRows, int numCols, QWidget *parent = 0, const char *name = 0) : QTable(numRows, numCols, parent, name) {} + + QWidget *beginEdit(int row, int col, bool replace) { + QWidget *w = QTable::beginEdit(row, col, replace); + ((QLineEdit*) w)->selectAll(); + return w; + } + +}; + +QalculateEditMatrixVectorDialog::QalculateEditMatrixVectorDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Variable"), Ok | Cancel | Help, Ok, true) { + + names_edit_dialog = NULL; + edited_variable = NULL; + + setMainWidget(new QWidget(this)); + QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint()); + grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 0, 0); + nameEdit = new KLineEdit(mainWidget()); + grid->addWidget(nameEdit, 0, 1); + QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 1, 1, 0, 1); + namesLabel = new QLabel(mainWidget()); + namesLabel->setAlignment(Qt::AlignRight); + namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + hbox->addWidget(namesLabel); + namesButton = new QPushButton(i18n("Names Details"), mainWidget()); + hbox->addWidget(namesButton); + grid->addWidget(new QLabel(i18n("Category:"), mainWidget()), 2, 0); + categoryCombo = new KComboBox(mainWidget()); + categoryCombo->setEditable(true); + grid->addWidget(categoryCombo, 2, 1); + grid->addWidget(new QLabel(i18n("Descriptive name:"), mainWidget()), 3, 0); + titleEdit = new KLineEdit(mainWidget()); + grid->addWidget(titleEdit, 3, 1); + grid->addWidget(new QLabel(i18n("Rows:"), mainWidget()), 4, 0); + rowsBox = new QSpinBox(1, 1000, 1, mainWidget()); + grid->addWidget(rowsBox, 4, 1); + grid->addWidget(new QLabel(i18n("Columns:"), mainWidget()), 5, 0); + columnsBox = new QSpinBox(1, 1000, 1, mainWidget()); + grid->addWidget(columnsBox, 5, 1); + hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 6, 6, 0, 1); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + QButtonGroup *group = new QButtonGroup(); + matrixButton = new QRadioButton(i18n("Matrix"), mainWidget()); + group->insert(matrixButton, 0); + hbox->addWidget(matrixButton); + vectorButton = new QRadioButton(i18n("Vector"), mainWidget()); + group->insert(vectorButton, 1); + hbox->addWidget(vectorButton); + elementsLabel = new QLabel(i18n("Elements:"), mainWidget()); + grid->addMultiCellWidget(elementsLabel, 7, 7, 0, 1); + elementsTable = new QalculateEditMatrixTable(0, 0, mainWidget()); + grid->addMultiCellWidget(elementsTable, 8, 8, 0, 1); + + connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames())); + connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&))); + connect(rowsBox, SIGNAL(valueChanged(int)), this, SLOT(rowsChanged(int))); + connect(columnsBox, SIGNAL(valueChanged(int)), this, SLOT(columnsChanged(int))); + connect(group, SIGNAL(clicked(int)), this, SLOT(typeChanged(int))); + +} + +QalculateEditMatrixVectorDialog::~QalculateEditMatrixVectorDialog() {} + +void QalculateEditMatrixVectorDialog::slotHelp() { + KApplication::kApplication()->invokeHelp("qalculate-vectors-matrices"); +} + +void QalculateEditMatrixVectorDialog::typeChanged(int i) { + if(i == 0) { + elementsLabel->setText(i18n("Elements:")); + bool b = true; + for(int index_r = elementsTable->numRows() - 1; index_r >= 0 && b; index_r--) { + for(int index_c = elementsTable->numCols() - 1; index_c >= 0; index_c--) { + if(elementsTable->text(index_r, index_c).isEmpty()) { + elementsTable->setText(index_r, index_c, "0"); + } else { + b = false; + break; + } + } + } + } else { + elementsLabel->setText(i18n("Elements (in horizontal order):")); + } +} +void QalculateEditMatrixVectorDialog::rowsChanged(int i) { + int r = elementsTable->numRows(); + elementsTable->setNumRows(i); + bool b = matrixButton->isChecked(); + for(int index_r = r; index_r < i; index_r++) { + for(int index_c = 0; index_c < elementsTable->numCols(); index_c++) { + if(b) elementsTable->setItem(index_r, index_c, new QalculateEditMatrixVectorTableItem(elementsTable, "0")); + else elementsTable->setItem(index_r, index_c, new QalculateEditMatrixVectorTableItem(elementsTable)); + } + } +} +void QalculateEditMatrixVectorDialog::columnsChanged(int i) { + int c = elementsTable->numCols(); + elementsTable->setNumCols(i); + bool b = matrixButton->isChecked(); + for(int index_r = 0; index_r < elementsTable->numRows(); index_r++) { + for(int index_c = c; index_c < i; index_c++) { + if(b) elementsTable->setItem(index_r, index_c, new QalculateEditMatrixVectorTableItem(elementsTable, "0")); + else elementsTable->setItem(index_r, index_c, new QalculateEditMatrixVectorTableItem(elementsTable)); + } + } +} + +KnownVariable *QalculateEditMatrixVectorDialog::newVector(QString category) { + return editVariable(category, NULL, NULL, false, true); +} +KnownVariable *QalculateEditMatrixVectorDialog::newMatrix(QString category) { + return editVariable(category, NULL, NULL, false, false); +} + +void QalculateEditMatrixVectorDialog::slotOk() { + string str = nameEdit->text().ascii(); + remove_blank_ends(str); + if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) { + //no name -- open dialog again + nameEdit->setFocus(); + KMessageBox::error(this, i18n("Empty name field")); + return; + } + //variable with the same name exists -- overwrite or open dialog again + if((!edited_variable || !edited_variable->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->variableNameTaken(str, edited_variable) && KMessageBox::questionYesNo(this, i18n("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) { + nameEdit->setFocus(); + return; + } + KnownVariable *v = edited_variable; + if(!v) { + //no need to create a new variable when a variable with the same name exists + Variable *var = CALCULATOR->getActiveVariable(str); + if(var && var->isLocal() && var->isKnown()) v = (KnownVariable*) var; + } + MathStructure mstruct_new; + if(!init_value) { + int r = rowsBox->value(); + int c = columnsBox->value(); + if(vectorButton->isChecked()) { + mstruct_new.clearVector(); + string str2; + for(int index_r = 0; index_r < r; index_r++) { + for(int index_c = 0; index_c < c; index_c++) { + if(!elementsTable->text(index_r, index_c).isEmpty()) { + str2 = elementsTable->text(index_r, index_c).ascii(); + remove_blank_ends(str2); + if(!str2.empty()) { + mstruct_new.addChild(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str2, evalops.parse_options))); + } + } + } + } + } else { + mstruct_new.clearMatrix(); + mstruct_new.resizeMatrix(r, c, m_undefined); + for(int index_r = 0; index_r < r; index_r++) { + for(int index_c = 0; index_c < c; index_c++) { + if(elementsTable->text(index_r, index_c).isEmpty()) mstruct_new.setElement(m_zero, index_r + 1, index_c + 1); + else mstruct_new.setElement(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(elementsTable->text(index_r, index_c).ascii(), evalops.parse_options)), index_r + 1, index_c + 1); + } + } + } + } + bool add_var = false; + if(v) { + //update existing variable + v->setLocal(true); + if(!v->isBuiltin()) { + if(init_value) { + v->set(*init_value); + } else { + v->set(mstruct_new); + } + } + } else { + //new variable + if(force_init_value && init_value) { + //forced value + v = new KnownVariable("", "", *init_value, "", true); + } else { + v = new KnownVariable("", "", mstruct_new, "", true); + } + add_var = true; + } + v->setCategory(categoryCombo->lineEdit()->text().ascii()); + v->setTitle(titleEdit->text().ascii()); + if(!v->isBuiltin()) { + if(names_edit_dialog) { + names_edit_dialog->saveNames(v, str.c_str()); + } else { + if(v->countNames() == 0) { + ExpressionName ename(str); + ename.reference = true; + v->setName(ename, 1); + } else { + v->setName(str, 1); + } + } + } + if(add_var) { + CALCULATOR->addVariable(v); + } + edited_variable = v; + accept(); +} + +KnownVariable *QalculateEditMatrixVectorDialog::editVariable(QString category, KnownVariable *v, MathStructure *initial_value, bool force_value, bool create_vector) { + + nameEdit->setFocus(); + + if((v && !v->get().isVector()) || (initial_value && !initial_value->isVector())) { + return NULL; + } + + if(names_edit_dialog) { + delete names_edit_dialog; + names_edit_dialog = NULL; + } + edited_variable = v; + + if(initial_value) { + create_vector = !initial_value->isMatrix(); + } else if(v) { + create_vector = !v->get().isMatrix(); + } + if(create_vector) { + vectorButton->setChecked(true); + elementsLabel->setText(i18n("Elements (in horizontal order):")); + } else { + matrixButton->setChecked(true); + elementsLabel->setText(i18n("Elements:")); + } + + if(create_vector) { + if(v) { + if(v->isLocal()) + setCaption(i18n("Edit Vector")); + else + setCaption(i18n("Edit Vector (global)")); + } else { + setCaption(i18n("New Vector")); + } + } else { + if(v) { + if(v->isLocal()) + setCaption(i18n("Edit Matrix")); + else + setCaption(i18n("Edit Matrix (global)")); + } else { + setCaption(i18n("New Matrix")); + } + } + + actionButton(Ok)->setEnabled(true); + + namesLabel->setText(""); + + //QStringList cats; + QString catstr; + categoryCombo->clear(); + tree_struct *item, *item2; + variable_cats.it = variable_cats.items.begin(); + if(variable_cats.it != variable_cats.items.end()) { + item = &*variable_cats.it; + ++variable_cats.it; + item->it = item->items.begin(); + } else { + item = NULL; + } + + catstr = ""; + while(item) { + if(!catstr.isEmpty()) catstr += "/"; + catstr += item->item.c_str(); + categoryCombo->insertItem(catstr); + while(item && item->it == item->items.end()) { + int str_i = catstr.findRev("/"); + if(str_i < 0) { + catstr = ""; + } else { + catstr.truncate(str_i); + } + item = item->parent; + } + if(item) { + item2 = &*item->it; + ++item->it; + item = item2; + item->it = item->items.begin(); + } + } + + int r = 4, c = 4; + const MathStructure *old_vctr = NULL; + if(v) { + if(create_vector) { + old_vctr = &v->get(); + } else { + c = v->get().columns(); + r = v->get().rows(); + } + set_name_label_and_entry(v, nameEdit, namesLabel); + nameEdit->setReadOnly(v->isBuiltin()); + rowsBox->setEnabled(!v->isBuiltin()); + columnsBox->setEnabled(!v->isBuiltin()); + matrixButton->setEnabled(!v->isBuiltin()); + vectorButton->setEnabled(!v->isBuiltin()); + elementsTable->setReadOnly(v->isBuiltin()); + categoryCombo->lineEdit()->setText(v->category().c_str()); + titleEdit->setText(v->title(false).c_str()); + } else { + nameEdit->setReadOnly(false); + rowsBox->setEnabled(true); + columnsBox->setEnabled(true); + matrixButton->setEnabled(true); + vectorButton->setEnabled(true); + elementsTable->setReadOnly(false); + + //fill in default values + nameEdit->setText(CALCULATOR->getName().c_str()); + namesLabel->setText(""); + categoryCombo->lineEdit()->setText(category); + titleEdit->setText(""); + if(force_value) { + if(create_vector) { + old_vctr = initial_value; + } else { + c = initial_value->columns(); + r = initial_value->rows(); + } + rowsBox->setEnabled(false); + columnsBox->setEnabled(false); + matrixButton->setEnabled(false); + vectorButton->setEnabled(false); + elementsTable->setReadOnly(true); + } + } + + if(create_vector) { + if(old_vctr) { + r = old_vctr->countChildren(); + c = (int) ::sqrt(r) + 4; + if(r % c > 0) { + r = r / c + 1; + } else { + r = r / c; + } + } else { + c = 4; + r = 4; + } + } + + rowsBox->setValue(r); + columnsBox->setValue(c); + elementsTable->setNumRows(r); + elementsTable->setNumCols(c); + + int timeout; + if(force_value) timeout = 3000 / (r * c); + else timeout = 3000; + PrintOptions po; + po.number_fraction_format = FRACTION_DECIMAL_EXACT; + for(int index_r = 0; index_r < r; index_r++) { + for(int index_c = 0; index_c < c; index_c++) { + if(create_vector) { + if(old_vctr && index_r * c + index_c < (int) old_vctr->countChildren()) { + elementsTable->setText(index_r, index_c, old_vctr->getChild(index_r * c + index_c + 1)->print(po).c_str()); + } else { + elementsTable->setText(index_r, index_c, ""); + } + } else { + if(v) { + elementsTable->setText(index_r, index_c, v->get().getElement(index_r + 1, index_c + 1)->print(po).c_str()); + } else if(initial_value) { + elementsTable->setText(index_r, index_c, initial_value->getElement(index_r + 1, index_c + 1)->print(po).c_str()); + } else { + elementsTable->setText(index_r, index_c, "0"); + } + } + } + } + + init_value = initial_value; + force_init_value = force_value; + + if(exec() == QDialog::Accepted) { + v = edited_variable; + edited_variable = NULL; + return v; + } + + edited_variable = NULL; + return NULL; +} + +void QalculateEditMatrixVectorDialog::editNames() { + if(!names_edit_dialog) { + names_edit_dialog = new QalculateEditNamesDialog(TYPE_VARIABLE, this); + names_edit_dialog->setNames(edited_variable, nameEdit->text(), false); + } else { + names_edit_dialog->setNames(edited_variable, nameEdit->text(), true); + } + names_edit_dialog->exec(); + names_edit_dialog->setNamesLE(nameEdit, namesLabel); +} + +void QalculateEditMatrixVectorDialog::nameChanged(const QString &name) { + if(name.isNull()) return; + if(!CALCULATOR->variableNameIsValid(name.ascii())) { + nameEdit->blockSignals(true); + nameEdit->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str()); + nameEdit->blockSignals(false); + } +} + +#if QT_VERSION >= 0x030200 +QalculateEditMatrixVectorTableItem::QalculateEditMatrixVectorTableItem(QTable *table) : QTableItem(table, QTableItem::OnTyping) {} +#else +QalculateEditMatrixVectorTableItem::QalculateEditMatrixVectorTableItem(QTable *table) : QTableItem(table, QTableItem::OnTyping, QString::null) {} +#endif +QalculateEditMatrixVectorTableItem::QalculateEditMatrixVectorTableItem(QTable *table, const QString & text) : QTableItem(table, QTableItem::OnTyping, text) {} + +int QalculateEditMatrixVectorTableItem::alignment() const {return Qt::AlignRight;} + +#include "qalculateeditmatrixvectordialog.moc" + diff --git a/src/qalculateeditmatrixvectordialog.h b/src/qalculateeditmatrixvectordialog.h new file mode 100644 index 0000000..6ecd146 --- /dev/null +++ b/src/qalculateeditmatrixvectordialog.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEEDITMATRIXVECTORDIALOG_H +#define QALCULATEEDITMATRIXVECTORDIALOG_H + +#include + +class QLabel; +class QSpinBox; +class QTable; +class QRadioButton; +class KComboBox; +class KLineEdit; +class QPushButton; +class MathStructure; +class QalculateEditNamesDialog; +class KnownVariable; + +/** +@author Niklas Knutsson +*/ +class QalculateEditMatrixVectorDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateEditMatrixVectorDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateEditMatrixVectorDialog(); + + KnownVariable *newMatrix(QString category = QString::null); + KnownVariable *newVector(QString category = QString::null); + KnownVariable *editVariable(QString category = QString::null, KnownVariable *v = NULL, MathStructure *initial_value = NULL, bool force_value = false, bool create_vector = false); + + QalculateEditNamesDialog *names_edit_dialog; + KnownVariable *edited_variable; + KComboBox *categoryCombo; + KLineEdit *nameEdit, *titleEdit; + QLabel *namesLabel, *elementsLabel; + QRadioButton *matrixButton, *vectorButton; + QTable *elementsTable; + QSpinBox *rowsBox, *columnsBox; + QPushButton *namesButton; + +private: + + MathStructure *init_value; + bool force_init_value; + +public slots: + + void typeChanged(int); + void rowsChanged(int); + void columnsChanged(int); + void editNames(); + void nameChanged(const QString&); + +protected slots: + + void slotHelp(); + void slotOk(); + +}; + +#endif diff --git a/src/qalculateeditnamesdialog.cpp b/src/qalculateeditnamesdialog.cpp new file mode 100644 index 0000000..1a79c51 --- /dev/null +++ b/src/qalculateeditnamesdialog.cpp @@ -0,0 +1,275 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateeditnamesdialog.h" +#include "qalculate_kde_utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +QalculateEditNamesDialog::QalculateEditNamesDialog(int item_type, QWidget *parent, const char *name) : KDialog(parent, name, true) { + + setCaption(i18n("Edit Names")); + + i_type = item_type; + + QVBoxLayout *layout = new QVBoxLayout(this, marginHint(), spacingHint()); + + namesView = new KListView(this); + namesView->addColumn(i18n("Name")); + namesView->addColumn(i18n("Abbreviation")); + namesView->setColumnAlignment(1, Qt::AlignCenter); + namesView->addColumn(i18n("Plural")); + namesView->setColumnAlignment(2, Qt::AlignCenter); + namesView->addColumn(i18n("Reference")); + namesView->setColumnAlignment(3, Qt::AlignCenter); + namesView->addColumn(i18n("Avoid Input")); + namesView->setColumnAlignment(4, Qt::AlignCenter); + namesView->addColumn(i18n("Unicode")); + namesView->setColumnAlignment(5, Qt::AlignCenter); + namesView->addColumn(i18n("Suffix")); + namesView->setColumnAlignment(6, Qt::AlignCenter); + namesView->addColumn(i18n("Case Sensitive")); + namesView->setColumnAlignment(7, Qt::AlignCenter); + namesView->setSorting(-1); + namesView->setItemsRenameable(true); + namesView->setItemsMovable(true); + namesView->setDragEnabled(true); + namesView->setAcceptDrops(true); + layout->addWidget(namesView); + + QHBoxLayout *buttonLayout = new QHBoxLayout(layout, spacingHint()); + newButton = new QPushButton(i18n("New"), this); + buttonLayout->addWidget(newButton); + deleteButton = new QPushButton(i18n("Delete"), this); + deleteButton->setEnabled(false); + buttonLayout->addWidget(deleteButton); + buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + buttonClose = new KPushButton(KStdGuiItem::close(), this); + buttonClose->setAutoDefault(true); + buttonClose->setDefault(true); + buttonLayout->addWidget(buttonClose); + + connect(namesView, SIGNAL(selectionChanged()), this, SLOT(nameSelectionChanged())); + connect(buttonClose, SIGNAL(clicked()), this, SLOT(accept())); + connect(newButton, SIGNAL(clicked()), this, SLOT(newName())); + connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteName())); + connect(namesView, SIGNAL(clicked(QListViewItem*, const QPoint&, int)), this, SLOT(itemClicked(QListViewItem*, const QPoint&, int))); + connect(namesView->renameLineEdit(), SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&))); + +} + +QalculateEditNamesDialog::~QalculateEditNamesDialog() {} + +void QalculateEditNamesDialog::newName() { + ExpressionName name; + QListViewItem *i = new KListViewItem(namesView, namesView->lastChild(), "", i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No"), i18n("No")); + namesView->setSelected(i, true); + qApp->processEvents(); + namesView->rename(i, 0); +} + +void QalculateEditNamesDialog::setNames(ExpressionItem *item, const QString &namestr, bool names_edited) { + + if(!names_edited) { + deleteButton->setEnabled(false); + namesView->clear(); + } + if(!names_edited && item && item->countNames() > 0) { + QListViewItem *i_prev = NULL; + for(size_t index = 1; index <= item->countNames(); index++) { + const ExpressionName *ename = &item->getName(index); + QListViewItem *i = new KListViewItem(namesView, i_prev); + i_prev = i; + if(ename->abbreviation) + i->setText(1, i18n("Yes")); + else + i->setText(1, i18n("No")); + if(ename->plural) + i->setText(2, i18n("Yes")); + else + i->setText(2, i18n("No")); + if(ename->reference) + i->setText(3, i18n("Yes")); + else + i->setText(3, i18n("No")); + if(ename->avoid_input) + i->setText(4, i18n("Yes")); + else + i->setText(4, i18n("No")); + if(ename->unicode) + i->setText(5, i18n("Yes")); + else + i->setText(5, i18n("No")); + if(ename->suffix) + i->setText(6, i18n("Yes")); + else + i->setText(6, i18n("No")); + if(ename->case_sensitive) + i->setText(7, i18n("Yes")); + else + i->setText(7, i18n("No")); + if(index == 1 && !namestr.isEmpty()) { + i->setText(0, namestr); + } else { + i->setText(0, ename->name.c_str()); + } + } + } else if(!namestr.isEmpty()) { + if(names_edited) { + QListViewItemIterator it(namesView); + if(it.current()) + it.current()->setText(0, namestr); + } else { + ExpressionName ename(namestr.ascii()); + QListViewItem *i = new KListViewItem(namesView, ename.name.c_str()); + if(ename.abbreviation) + i->setText(1, i18n("Yes")); + else + i->setText(1, i18n("No")); + if(ename.plural) + i->setText(2, i18n("Yes")); + else + i->setText(2, i18n("No")); + if(ename.reference) + i->setText(3, i18n("Yes")); + else + i->setText(3, i18n("No")); + if(ename.avoid_input) + i->setText(4, i18n("Yes")); + else + i->setText(4, i18n("No")); + if(ename.unicode) + i->setText(5, i18n("Yes")); + else + i->setText(5, i18n("No")); + if(ename.suffix) + i->setText(6, i18n("Yes")); + else + i->setText(6, i18n("No")); + if(ename.case_sensitive) + i->setText(7, i18n("Yes")); + else + i->setText(7, i18n("No")); + } + } +} +void QalculateEditNamesDialog::saveNames(ExpressionItem *item, const QString &str) { + item->clearNames(); + QListViewItemIterator it(namesView); + if(it.current()) { + bool b = false; + while(it.current()) { + ExpressionName ename; + if(b || str.isEmpty()) + ename.name = it.current()->text(0).ascii(); + else + ename.name = str.ascii(); + ename.abbreviation = (it.current()->text(1) == i18n("Yes")); + ename.plural = (it.current()->text(2) == i18n("Yes")); + ename.reference = (it.current()->text(3) == i18n("Yes")); + ename.avoid_input = (it.current()->text(4) == i18n("Yes")); + ename.unicode = (it.current()->text(5) == i18n("Yes")); + ename.suffix = (it.current()->text(6) == i18n("Yes")); + ename.case_sensitive = (it.current()->text(7) == i18n("Yes")); + item->addName(ename); + ++it; + b = true; + } + } else { + item->addName(str.ascii()); + } +} +void QalculateEditNamesDialog::setNamesLE(QLineEdit *entry, QLabel *label) { + int index = 0; + QString str; + QListViewItemIterator it(namesView); + while(it.current()) { + if(index == 0) { + entry->setText(it.current()->text(0)); + } else { + if(index == 1) { + str = "+ "; + } else { + str += ", "; + } + str += it.current()->text(0); + } + ++it; + index++; + } + label->setText(str); +} +bool QalculateEditNamesDialog::isEmpty() { + return namesView->childCount() <= 0; +} + +void QalculateEditNamesDialog::deleteName() { + namesView->removeItem(namesView->selectedItem()); +} + +void QalculateEditNamesDialog::itemClicked(QListViewItem *i, const QPoint &, int c) { + if(i && c > 0) { + if(i->text(c) == i18n("Yes")) + i->setText(c, i18n("No")); + else + i->setText(c, i18n("Yes")); + if(c == 1) + i->setText(7, i->text(c)); + } +} + +void QalculateEditNamesDialog::nameSelectionChanged() { + deleteButton->setEnabled(namesView->selectedItem() != NULL); +} + +void QalculateEditNamesDialog::nameChanged(const QString &name) { + if(name.isNull()) return; + namesView->renameLineEdit()->blockSignals(true); + switch(i_type) { + case TYPE_VARIABLE: { + if(!CALCULATOR->variableNameIsValid(name.ascii())) { + namesView->renameLineEdit()->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str()); + } + break; + } + case TYPE_UNIT: { + if(!CALCULATOR->unitNameIsValid(name.ascii())) { + namesView->renameLineEdit()->setText(CALCULATOR->convertToValidUnitName(name.ascii()).c_str()); + } + break; + } + case TYPE_FUNCTION: { + if(!CALCULATOR->functionNameIsValid(name.ascii())) { + namesView->renameLineEdit()->setText(CALCULATOR->convertToValidFunctionName(name.ascii()).c_str()); + } + break; + } + } + namesView->renameLineEdit()->blockSignals(false); +} + + +#include "qalculateeditnamesdialog.moc" diff --git a/src/qalculateeditnamesdialog.h b/src/qalculateeditnamesdialog.h new file mode 100644 index 0000000..42f49af --- /dev/null +++ b/src/qalculateeditnamesdialog.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEEDITNAMESDIALOG_H +#define QALCULATEEDITNAMESDIALOG_H + +#include + +class ExpressionItem; +class KListView; +class QPushButton; +class QLineEdit; +class QLabel; +class QListViewItem; + +/** +@author Niklas Knutsson +*/ +class QalculateEditNamesDialog : public KDialog { + + Q_OBJECT + +public: + + QalculateEditNamesDialog(int item_type, QWidget *parent = 0, const char *name = 0); + virtual ~QalculateEditNamesDialog(); + + void saveNames(ExpressionItem *item, const QString &str = QString::null); + void setNames(ExpressionItem *item = NULL, const QString &namestr = QString::null, bool names_edited = false); + bool isEmpty(); + void setNamesLE(QLineEdit *entry, QLabel *label); + + KListView* namesView; + QPushButton* newButton; + QPushButton* deleteButton; + QPushButton* buttonClose; + int i_type; + +public slots: + + virtual void itemClicked(QListViewItem*, const QPoint&, int); + virtual void newName(); + virtual void deleteName(); + virtual void nameChanged(const QString&); + virtual void nameSelectionChanged(); + +}; + +#endif diff --git a/src/qalculateeditunitdialog.cpp b/src/qalculateeditunitdialog.cpp new file mode 100644 index 0000000..3bf155f --- /dev/null +++ b/src/qalculateeditunitdialog.cpp @@ -0,0 +1,425 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateeditunitdialog.h" +#include "qalculate_kde_utils.h" +#include "qalculateeditnamesdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern PrintOptions printops; +extern EvaluationOptions evalops; +extern tree_struct unit_cats; + +QalculateEditUnitDialog::QalculateEditUnitDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Unit"), Ok | Cancel | Help, Ok, true) { + + names_edit_dialog = NULL; + edited_unit = NULL; + + QVBox *box = makeVBoxMainWidget(); + + grid1 = new QGroupBox(1, Qt::Horizontal, i18n("Name"), box); + grid1->setInsideMargin(spacingHint()); + grid1->setInsideSpacing(spacingHint()); + QWidget *widget = new QWidget(grid1); + QGridLayout *grid = new QGridLayout(widget, 1, 1, 0, spacingHint()); + grid->addWidget(new QLabel(i18n("Name:"), widget), 0, 0); + nameEdit = new KLineEdit(widget); + grid->addWidget(nameEdit, 0, 1); + QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 1, 1, 0, 1); + namesLabel = new QLabel(widget); + namesLabel->setAlignment(Qt::AlignRight); + namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + hbox->addWidget(namesLabel); + namesButton = new QPushButton(i18n("Names Details"), widget); + hbox->addWidget(namesButton); + grid->addWidget(new QLabel(i18n("Descriptive name:"), widget), 2, 0); + titleEdit = new KLineEdit(widget); + grid->addWidget(titleEdit, 2, 1); + hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 3, 3, 0, 1); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + hideButton = new QCheckBox(i18n("Hide unit"), widget); + hbox->addWidget(hideButton); + + grid2 = new QGroupBox(1, Qt::Horizontal, i18n("Type"), box); + grid2->setInsideMargin(spacingHint()); + grid2->setInsideSpacing(spacingHint()); + widget = new QWidget(grid2); + grid = new QGridLayout(widget, 1, 1, 0, spacingHint()); + grid->addWidget(new QLabel(i18n("Class:"), widget), 0, 0); + classCombo = new KComboBox(widget); + grid->addWidget(classCombo, 0, 1); + classCombo->insertItem(i18n("Base Unit")); + classCombo->insertItem(i18n("Alias")); + classCombo->insertItem(i18n("Composite Unit")); + classCombo->setMaximumWidth(250); + grid->addWidget(new QLabel(i18n("Category:"), widget), 1, 0); + categoryCombo = new KComboBox(widget); + grid->addWidget(categoryCombo, 1, 1); + categoryCombo->setMaximumWidth(250); + categoryCombo->setEditable(true); + grid->addWidget(new QLabel(i18n("System:"), widget), 2, 0); + systemCombo = new KComboBox(widget); + grid->addWidget(systemCombo, 2, 1); + systemCombo->insertItem(i18n("SI")); + systemCombo->insertItem(i18n("CGS")); + systemCombo->insertItem(i18n("Imperial")); + systemCombo->insertItem(i18n("US Survey")); + systemCombo->setMaximumWidth(250); + systemCombo->setEditable(true); + + grid3 = new QGroupBox(1, Qt::Horizontal, i18n("Relation"), box); + grid3->setInsideMargin(spacingHint()); + grid3->setInsideSpacing(spacingHint()); + widget = new QWidget(grid3); + grid = new QGridLayout(widget, 1, 1, 0, spacingHint()); + grid->addWidget(new QLabel(i18n("Base unit:"), widget), 0, 0); + baseEdit = new KLineEdit(widget); + grid->addWidget(baseEdit, 0, 1); + exponentLabel = new QLabel(i18n("Exponent:"), widget); + grid->addWidget(exponentLabel, 1, 0); + exponentBox = new QSpinBox(-9, 9, 1, widget); + grid->addWidget(exponentBox, 1, 1); + relationLabel = new QLabel(i18n("Relation:"), widget); + grid->addWidget(relationLabel, 2, 0); + relationEdit = new KLineEdit(widget); + grid->addWidget(relationEdit, 2, 1); + hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 3, 3, 0, 1); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + relationExactButton = new QCheckBox(i18n("Relation is exact"), widget); + hbox->addWidget(relationExactButton); + inverseRelationLabel = new QLabel(i18n("Inverse relation:"), widget); + grid->addWidget(inverseRelationLabel, 4, 0); + inverseRelationEdit = new KLineEdit(widget); + grid->addWidget(inverseRelationEdit, 4, 1); + + connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames())); + connect(classCombo, SIGNAL(activated(int)), this, SLOT(classChanged(int))); + connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&))); + +} + +QalculateEditUnitDialog::~QalculateEditUnitDialog() {} + +void QalculateEditUnitDialog::slotHelp() { + KApplication::kApplication()->invokeHelp("qalculate-unit-creation"); +} +void QalculateEditUnitDialog::slotOk() { + + string str = nameEdit->text().ascii(); + remove_blank_ends(str); + if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) { + //no name -- open dialog again + nameEdit->setFocus(); + KMessageBox::error(this, i18n("Empty name field")); + return; + } + //unit with the same name exists -- overwrite or open dialog again + if((!edited_unit || !edited_unit->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->unitNameTaken(str, edited_unit) && KMessageBox::questionYesNo(this, i18n("A variable or unit with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) { + nameEdit->setFocus(); + return; + } + + Unit *u = edited_unit; + + bool add_unit = false; + if(u) { + //edited an existing unit -- update unit + u->setLocal(true); + int i1 = classCombo->currentItem(); + switch(u->subtype()) { + case SUBTYPE_ALIAS_UNIT: { + if(i1 != 1) { + u->destroy(); + u = NULL; + break; + } + if(!u->isBuiltin()) { + AliasUnit *au = (AliasUnit*) u; + Unit *bu = CALCULATOR->getUnit(baseEdit->text().ascii()); + if(!bu) bu = CALCULATOR->getCompositeUnit(baseEdit->text().ascii()); + if(!bu) { + baseEdit->setFocus(); + KMessageBox::error(this, i18n("Base unit does not exist")); + return; + } + au->setBaseUnit(bu); + au->setExpression(CALCULATOR->unlocalizeExpression(relationEdit->text().ascii(), evalops.parse_options)); + au->setInverseExpression(CALCULATOR->unlocalizeExpression(inverseRelationEdit->text().ascii(), evalops.parse_options)); + au->setExponent(exponentBox->value()); + au->setApproximate(!relationExactButton->isChecked()); + } + break; + } + case SUBTYPE_COMPOSITE_UNIT: { + if(i1 != 2) { + u->destroy(); + u = NULL; + break; + } + if(!u->isBuiltin()) { + ((CompositeUnit*) u)->setBaseExpression(baseEdit->text().ascii()); + } + break; + } + case SUBTYPE_BASE_UNIT: { + if(i1 != 0) { + u->destroy(); + u = NULL; + break; + } + break; + } + } + if(u) { + u->setTitle(titleEdit->text().ascii()); + u->setCategory(categoryCombo->lineEdit()->text().ascii()); + } + } + if(!u) { + //new unit + switch(classCombo->currentItem()) { + case 1: { + Unit *bu = CALCULATOR->getUnit(baseEdit->text().ascii()); + if(!bu) bu = CALCULATOR->getCompositeUnit(baseEdit->text().ascii()); + if(!bu) { + baseEdit->setFocus(); + KMessageBox::error(this, i18n("Base unit does not exist")); + return; + } + u = new AliasUnit(categoryCombo->lineEdit()->text().ascii(), "", "", "", titleEdit->text().ascii(), bu, CALCULATOR->unlocalizeExpression(relationEdit->text().ascii(), evalops.parse_options), exponentBox->value(), CALCULATOR->unlocalizeExpression(inverseRelationEdit->text().ascii(), evalops.parse_options), true); + ((AliasUnit*) u)->setApproximate(!relationExactButton->isChecked()); + break; + } + case 2: { + CompositeUnit *cu = new CompositeUnit(categoryCombo->lineEdit()->text().ascii(), "", titleEdit->text().ascii(), baseEdit->text().ascii(), true); + u = cu; + break; + } + default: { + u = new Unit(categoryCombo->lineEdit()->text().ascii(), "", "", "", titleEdit->text().ascii(), true); + break; + } + } + add_unit = true; + } + if(u) { + u->setHidden(hideButton->isChecked()); + if(!u->isBuiltin()) { + u->setSystem(systemCombo->lineEdit()->text().ascii()); + if(names_edit_dialog) { + names_edit_dialog->saveNames(u, str.c_str()); + } else { + if(u->countNames() == 0) { + ExpressionName ename(str); + ename.reference = true; + u->setName(ename, 1); + } else { + u->setName(str, 1); + } + } + } + if(add_unit) { + CALCULATOR->addUnit(u); + } + } + edited_unit = u; + + accept(); + +} + + +void QalculateEditUnitDialog::classChanged(int i) { + exponentBox->setEnabled(i == 1); + relationEdit->setEnabled(i == 1); + relationExactButton->setEnabled(i == 1); + inverseRelationEdit->setEnabled(i == 1); + exponentLabel->setEnabled(i == 1); + relationLabel->setEnabled(i == 1); + inverseRelationLabel->setEnabled(i == 1); + grid3->setEnabled(i != 0); +} + +Unit *QalculateEditUnitDialog::editUnit(QString category, Unit *u) { + + nameEdit->setFocus(); + + if(names_edit_dialog) { + delete names_edit_dialog; + names_edit_dialog = NULL; + } + edited_unit = u; + if(u) { + if(u->isLocal()) + setCaption(i18n("Edit Unit")); + else + setCaption(i18n("Edit Unit (global)")); + } else { + setCaption(i18n("New Unit")); + } + + //QStringList cats; + QString catstr; + categoryCombo->clear(); + tree_struct *item, *item2; + unit_cats.it = unit_cats.items.begin(); + if(unit_cats.it != unit_cats.items.end()) { + item = &*unit_cats.it; + ++unit_cats.it; + item->it = item->items.begin(); + } else { + item = NULL; + } + + catstr = ""; + while(item) { + if(!catstr.isEmpty()) catstr += "/"; + catstr += item->item.c_str(); + categoryCombo->insertItem(catstr); + while(item && item->it == item->items.end()) { + int str_i = catstr.findRev("/"); + if(str_i < 0) { + catstr = ""; + } else { + catstr.truncate(str_i); + } + item = item->parent; + } + if(item) { + item2 = &*item->it; + ++item->it; + item = item2; + item->it = item->items.begin(); + } + } + + categoryCombo->lineEdit()->setText(category); + //clear entries + nameEdit->clear(); + titleEdit->clear(); + baseEdit->clear(); + relationEdit->clear(); + inverseRelationEdit->clear(); + systemCombo->lineEdit()->clear(); + exponentBox->setValue(1); + namesLabel->clear(); + actionButton(Ok)->setEnabled(true); + nameEdit->setReadOnly(u && u->isBuiltin()); + relationEdit->setReadOnly(u && u->isBuiltin()); + inverseRelationEdit->setReadOnly(u && u->isBuiltin()); + systemCombo->setEnabled(!u || !u->isBuiltin()); + classCombo->setEnabled(!u || !u->isBuiltin()); + baseEdit->setReadOnly(u && u->isBuiltin()); + if(u) { + //fill in original parameters + if(u->subtype() == SUBTYPE_BASE_UNIT) { + classCombo->setCurrentItem(0); + classChanged(0); + } else if(u->subtype() == SUBTYPE_ALIAS_UNIT) { + classCombo->setCurrentItem(1); + classChanged(1); + } else if(u->subtype() == SUBTYPE_COMPOSITE_UNIT) { + classCombo->setCurrentItem(2); + classChanged(2); + } + + set_name_label_and_entry(u, nameEdit, namesLabel); + systemCombo->lineEdit()->setText(u->system().c_str()); + hideButton->setChecked(u->isHidden()); + categoryCombo->lineEdit()->setText(u->category().c_str()); + titleEdit->setText(u->title(false).c_str()); + + switch(u->subtype()) { + case SUBTYPE_ALIAS_UNIT: { + AliasUnit *au = (AliasUnit*) u; + baseEdit->setText(((CompositeUnit*) (au->firstBaseUnit()))->preferredDisplayName(printops.abbreviate_names, true, false, false, &can_display_unicode_string_function, (void*) baseEdit).name.c_str()); + exponentBox->setValue(au->firstBaseExponent()); + relationEdit->setText(CALCULATOR->localizeExpression(au->expression()).c_str()); + inverseRelationEdit->setText(CALCULATOR->localizeExpression(au->inverseExpression()).c_str()); + relationExactButton->setChecked(!au->isApproximate()); + relationEdit->setEnabled(true); + inverseRelationEdit->setEnabled(true); + relationExactButton->setEnabled(!u->isBuiltin()); + exponentBox->setEnabled(!u->isBuiltin()); + baseEdit->setEnabled(true); + break; + } + case SUBTYPE_COMPOSITE_UNIT: { + baseEdit->setText(((CompositeUnit*) u)->print(false, printops.abbreviate_names, true, &can_display_unicode_string_function, (void*) baseEdit).c_str()); + baseEdit->setEnabled(true); + } + } + } else { + //default values + hideButton->setChecked(false); + relationExactButton->setChecked(true); + relationEdit->setText("1"); + classCombo->setCurrentItem(1); + classChanged(1); + } + + if(exec() == QDialog::Accepted) { + u = edited_unit; + edited_unit = NULL; + return u; + } + edited_unit = NULL; + return NULL; +} + +void QalculateEditUnitDialog::editNames() { + if(!names_edit_dialog) { + names_edit_dialog = new QalculateEditNamesDialog(TYPE_UNIT, this); + names_edit_dialog->setNames(edited_unit, nameEdit->text(), false); + } else { + names_edit_dialog->setNames(edited_unit, nameEdit->text(), true); + } + names_edit_dialog->exec(); + names_edit_dialog->setNamesLE(nameEdit, namesLabel); +} + +void QalculateEditUnitDialog::nameChanged(const QString &name) { + if(name.isNull()) return; + if(!CALCULATOR->unitNameIsValid(name.ascii())) { + nameEdit->blockSignals(true); + nameEdit->setText(CALCULATOR->convertToValidUnitName(name.ascii()).c_str()); + nameEdit->blockSignals(false); + } +} + + +#include "qalculateeditunitdialog.moc" + diff --git a/src/qalculateeditunitdialog.h b/src/qalculateeditunitdialog.h new file mode 100644 index 0000000..02655d8 --- /dev/null +++ b/src/qalculateeditunitdialog.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEEDITUNITDIALOG_H +#define QALCULATEEDITUNITDIALOG_H + +#include + +class QLabel; +class KComboBox; +class KLineEdit; +class QCheckBox; +class QPushButton; +class QSpinBox; +class MathStructure; +class QalculateEditNamesDialog; +class Unit; +class QGroupBox; + +/** +@author Niklas Knutsson +*/ +class QalculateEditUnitDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateEditUnitDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateEditUnitDialog(); + + Unit *editUnit(QString category = QString::null, Unit *u = NULL); + + QalculateEditNamesDialog *names_edit_dialog; + Unit *edited_unit; + KComboBox *categoryCombo, *classCombo, *systemCombo; + KLineEdit *nameEdit, *titleEdit, *baseEdit, *relationEdit, *inverseRelationEdit; + QLabel *namesLabel, *exponentLabel, *relationLabel, *inverseRelationLabel; + QCheckBox *relationExactButton, *hideButton; + QPushButton *namesButton; + QSpinBox *exponentBox; + QGroupBox *grid1, *grid2, *grid3; + +public slots: + + void editNames(); + void classChanged(int); + void nameChanged(const QString&); + +protected slots: + + void slotHelp(); + void slotOk(); + +}; + +#endif diff --git a/src/qalculateeditunknownvariabledialog.cpp b/src/qalculateeditunknownvariabledialog.cpp new file mode 100644 index 0000000..4e7dc42 --- /dev/null +++ b/src/qalculateeditunknownvariabledialog.cpp @@ -0,0 +1,308 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateeditunknownvariabledialog.h" +#include "qalculate_kde_utils.h" +#include "qalculateeditnamesdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern PrintOptions printops; +extern tree_struct variable_cats; + +QalculateEditUnknownVariableDialog::QalculateEditUnknownVariableDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Variable"), Ok | Cancel | Help, Ok, true) { + + names_edit_dialog = NULL; + edited_unknown = NULL; + + setMainWidget(new QWidget(this)); + QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint()); + grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 0, 0); + nameEdit = new KLineEdit(mainWidget()); + grid->addWidget(nameEdit, 0, 1); + QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 1, 1, 0, 1); + namesLabel = new QLabel(mainWidget()); + namesLabel->setAlignment(Qt::AlignRight); + namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + hbox->addWidget(namesLabel); + namesButton = new QPushButton(i18n("Names Details"), mainWidget()); + hbox->addWidget(namesButton); + assumptionsBox = new QCheckBox(i18n("Custom assumptions:"), mainWidget()); + grid->addMultiCellWidget(assumptionsBox, 2, 2, 0, 1); + typeLabel = new QLabel(i18n("Type"), mainWidget()); + grid->addWidget(typeLabel, 3, 0); + typeCombo = new KComboBox(mainWidget()); + typeCombo->setMaximumWidth(250); + typeCombo->setEditable(false); + typeCombo->insertItem(i18n("Unknown")); + typeCombo->insertItem(i18n("Not Matrix")); + typeCombo->insertItem(i18n("Number")); + typeCombo->insertItem(i18n("Complex Number")); + typeCombo->insertItem(i18n("Real Number")); + typeCombo->insertItem(i18n("Rational Number")); + typeCombo->insertItem(i18n("Integer")); + grid->addWidget(typeCombo, 3, 1); + signLabel = new QLabel(i18n("Sign"), mainWidget()); + grid->addWidget(signLabel, 4, 0); + signCombo = new KComboBox(mainWidget()); + signCombo->setMaximumWidth(250); + signCombo->setEditable(false); + signCombo->insertItem(i18n("Unknown")); + signCombo->insertItem(i18n("Positive")); + signCombo->insertItem(i18n("Non-Negative")); + signCombo->insertItem(i18n("Negative")); + signCombo->insertItem(i18n("Non-Positive")); + signCombo->insertItem(i18n("Non-Zero")); + grid->addWidget(signCombo, 4, 1); + grid->addWidget(new QLabel(i18n("Category:"), mainWidget()), 5, 0); + categoryCombo = new KComboBox(mainWidget()); + categoryCombo->setMaximumWidth(250); + categoryCombo->setEditable(true); + grid->addWidget(categoryCombo, 5, 1); + grid->addWidget(new QLabel(i18n("Descriptive name:"), mainWidget()), 6, 0); + titleEdit = new KLineEdit(mainWidget()); + grid->addWidget(titleEdit, 6, 1); + + connect(assumptionsBox, SIGNAL(toggled(bool)), typeCombo, SLOT(setEnabled(bool))); + connect(assumptionsBox, SIGNAL(toggled(bool)), signCombo, SLOT(setEnabled(bool))); + connect(assumptionsBox, SIGNAL(toggled(bool)), typeLabel, SLOT(setEnabled(bool))); + connect(assumptionsBox, SIGNAL(toggled(bool)), signLabel, SLOT(setEnabled(bool))); + connect(typeCombo, SIGNAL(activated(int)), this, SLOT(typeComboActivated(int))); + connect(signCombo, SIGNAL(activated(int)), this, SLOT(signComboActivated(int))); + connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames())); + connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&))); + +} + +QalculateEditUnknownVariableDialog::~QalculateEditUnknownVariableDialog() {} + +void QalculateEditUnknownVariableDialog::typeComboActivated(int i) { + if((AssumptionType) i <= ASSUMPTION_TYPE_COMPLEX && (AssumptionSign) signCombo->currentItem() != ASSUMPTION_SIGN_NONZERO) { + signCombo->blockSignals(true); + signCombo->setCurrentItem(ASSUMPTION_SIGN_UNKNOWN); + signCombo->blockSignals(false); + } +} +void QalculateEditUnknownVariableDialog::signComboActivated(int i) { + if((AssumptionSign) i != ASSUMPTION_SIGN_NONZERO && (AssumptionSign) i != ASSUMPTION_SIGN_UNKNOWN && (AssumptionType) typeCombo->currentItem() <= ASSUMPTION_TYPE_COMPLEX) { + typeCombo->blockSignals(true); + typeCombo->setCurrentItem(ASSUMPTION_TYPE_REAL); + typeCombo->blockSignals(false); + } +} + +void QalculateEditUnknownVariableDialog::slotHelp() { + KApplication::kApplication()->invokeHelp("qalculate-variable-creation"); +} +void QalculateEditUnknownVariableDialog::slotOk() { + + string str = nameEdit->text().ascii(); + remove_blank_ends(str); + if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) { + //no name -- open dialog again + nameEdit->setFocus(); + KMessageBox::error(this, i18n("Empty name field")); + return; + } + //variable with the same name exists -- overwrite or open dialog again + if((!edited_unknown || !edited_unknown->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->variableNameTaken(str, edited_unknown) && KMessageBox::questionYesNo(this, i18n("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) { + nameEdit->setFocus(); + return; + } + + UnknownVariable *v = edited_unknown; + if(!v) { + //no need to create a new variable when a variable with the same name exists + Variable *var = CALCULATOR->getActiveVariable(str); + if(var && var->isLocal() && !var->isKnown()) v = (UnknownVariable*) var; + } + bool add_var = false; + if(v) { + //update existing variable + v->setLocal(true); + } else { + //new unknown variable + v = new UnknownVariable("", "", "", true); + add_var = true; + } + if(!v->isBuiltin()) { + if(assumptionsBox->isChecked()) { + if(!v->assumptions()) v->setAssumptions(new Assumptions()); + v->assumptions()->setType((AssumptionType) typeCombo->currentItem()); + v->assumptions()->setSign((AssumptionSign) signCombo->currentItem()); + } else { + v->setAssumptions(NULL); + } + } + v->setCategory(categoryCombo->lineEdit()->text().ascii()); + v->setTitle(titleEdit->text().ascii()); + if(!v->isBuiltin()) { + if(names_edit_dialog) { + names_edit_dialog->saveNames(v, str.c_str()); + } else { + if(v->countNames() == 0) { + ExpressionName ename(str); + ename.reference = true; + v->setName(ename, 1); + } else { + v->setName(str, 1); + } + } + } + if(add_var) { + CALCULATOR->addVariable(v); + } + edited_unknown = v; + accept(); +} + + +UnknownVariable *QalculateEditUnknownVariableDialog::editVariable(QString category, UnknownVariable *v) { + + nameEdit->setFocus(); + + if(names_edit_dialog) { + delete names_edit_dialog; + names_edit_dialog = NULL; + } + edited_unknown = v; + if(v) { + if(v->isLocal()) + setCaption(i18n("Edit Unknown Variable")); + else + setCaption(i18n("Edit Unknown Variable (global)")); + } else { + setCaption(i18n("New Unknown Variable")); + } + + actionButton(Ok)->setEnabled(true); + + namesLabel->setText(""); + + //QStringList cats; + QString catstr; + categoryCombo->clear(); + tree_struct *item, *item2; + variable_cats.it = variable_cats.items.begin(); + if(variable_cats.it != variable_cats.items.end()) { + item = &*variable_cats.it; + ++variable_cats.it; + item->it = item->items.begin(); + } else { + item = NULL; + } + + catstr = ""; + while(item) { + if(!catstr.isEmpty()) catstr += "/"; + catstr += item->item.c_str(); + categoryCombo->insertItem(catstr); + while(item && item->it == item->items.end()) { + int str_i = catstr.findRev("/"); + if(str_i < 0) { + catstr = ""; + } else { + catstr.truncate(str_i); + } + item = item->parent; + } + if(item) { + item2 = &*item->it; + ++item->it; + item = item2; + item->it = item->items.begin(); + } + } + + if(v) { + //fill in original parameters + set_name_label_and_entry(v, nameEdit, namesLabel); + nameEdit->setReadOnly(v->isBuiltin()); + assumptionsBox->setEnabled(!v->isBuiltin()); + categoryCombo->lineEdit()->setText(v->category().c_str()); + titleEdit->setText(v->title(false).c_str()); + if(v->assumptions()) { + assumptionsBox->setChecked(true); + typeCombo->setCurrentItem(v->assumptions()->type()); + signCombo->setCurrentItem(v->assumptions()->sign()); + } else { + assumptionsBox->setChecked(false); + typeCombo->setCurrentItem(CALCULATOR->defaultAssumptions()->type()); + signCombo->setCurrentItem(CALCULATOR->defaultAssumptions()->sign()); + } + } else { + nameEdit->setReadOnly(false); + assumptionsBox->setChecked(true); + + //fill in default values + nameEdit->setText(CALCULATOR->getName().c_str()); + namesLabel->setText(""); + categoryCombo->lineEdit()->setText(category); + titleEdit->setText(""); + typeCombo->setCurrentItem(CALCULATOR->defaultAssumptions()->type()); + signCombo->setCurrentItem(CALCULATOR->defaultAssumptions()->sign()); + } + signLabel->setEnabled(!v || (!v->isBuiltin() && v->assumptions())); + typeLabel->setEnabled(!v || (!v->isBuiltin() && v->assumptions())); + signCombo->setEnabled(!v || (!v->isBuiltin() && v->assumptions())); + typeCombo->setEnabled(!v || (!v->isBuiltin() && v->assumptions())); + + if(exec() == QDialog::Accepted) { + v = edited_unknown; + edited_unknown = NULL; + return v; + } + edited_unknown = NULL; + return NULL; +} + +void QalculateEditUnknownVariableDialog::editNames() { + if(!names_edit_dialog) { + names_edit_dialog = new QalculateEditNamesDialog(TYPE_VARIABLE, this); + names_edit_dialog->setNames(edited_unknown, nameEdit->text(), false); + } else { + names_edit_dialog->setNames(edited_unknown, nameEdit->text(), true); + } + names_edit_dialog->exec(); + names_edit_dialog->setNamesLE(nameEdit, namesLabel); +} + +void QalculateEditUnknownVariableDialog::nameChanged(const QString &name) { + if(name.isNull()) return; + if(!CALCULATOR->variableNameIsValid(name.ascii())) { + nameEdit->blockSignals(true); + nameEdit->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str()); + nameEdit->blockSignals(false); + } +} + +#include "qalculateeditunknownvariabledialog.moc" + diff --git a/src/qalculateeditunknownvariabledialog.h b/src/qalculateeditunknownvariabledialog.h new file mode 100644 index 0000000..cfa499e --- /dev/null +++ b/src/qalculateeditunknownvariabledialog.h @@ -0,0 +1,70 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEEDITUNKNOWNVARIABLEDIALOG_H +#define QALCULATEEDITUNKNOWNVARIABLEDIALOG_H + +#include + +class QLabel; +class KComboBox; +class KLineEdit; +class QPushButton; +class MathStructure; +class QalculateEditNamesDialog; +class UnknownVariable; +class QCheckBox; + +/** +@author Niklas Knutsson +*/ +class QalculateEditUnknownVariableDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateEditUnknownVariableDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateEditUnknownVariableDialog(); + + UnknownVariable *editVariable(QString category = QString::null, UnknownVariable *v = NULL); + + QalculateEditNamesDialog *names_edit_dialog; + UnknownVariable *edited_unknown; + KComboBox *categoryCombo, *signCombo, *typeCombo; + KLineEdit *nameEdit, *titleEdit; + QLabel *namesLabel, *signLabel, *typeLabel; + QPushButton *namesButton; + QCheckBox *assumptionsBox; + +public slots: + + void editNames(); + void nameChanged(const QString&); + void signComboActivated(int); + void typeComboActivated(int); + +protected slots: + + void slotHelp(); + void slotOk(); + +}; + +#endif diff --git a/src/qalculateeditvariabledialog.cpp b/src/qalculateeditvariabledialog.cpp new file mode 100644 index 0000000..013dec0 --- /dev/null +++ b/src/qalculateeditvariabledialog.cpp @@ -0,0 +1,304 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateeditvariabledialog.h" +#include "qalculate_kde_utils.h" +#include "qalculateeditnamesdialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern PrintOptions printops; +extern EvaluationOptions evalops; +extern tree_struct variable_cats; + +QalculateEditVariableDialog::QalculateEditVariableDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Variable"), Ok | Cancel | Help, Ok, true) { + + names_edit_dialog = NULL; + edited_variable = NULL; + + setMainWidget(new QWidget(this)); + QGridLayout *grid = new QGridLayout(mainWidget(), 6, 2, 0, spacingHint()); + + nameLabel = new QLabel(i18n("Name:"), mainWidget()); + grid->addWidget(nameLabel, 0, 0); + nameEdit = new KLineEdit(mainWidget()); + grid->addWidget(nameEdit, 0, 1); + + QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 1, 1, 0, 1); + namesLabel = new QLabel(mainWidget()); + namesLabel->setAlignment(Qt::AlignRight); + namesLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); + hbox->addWidget(namesLabel); + namesButton = new QPushButton(i18n("Names Details"), mainWidget()); + hbox->addWidget(namesButton); + + valueLabel = new QLabel(i18n("Value:"), mainWidget()); + grid->addWidget(valueLabel, 2, 0); + valueEdit = new KLineEdit(mainWidget()); + grid->addWidget(valueEdit, 2, 1); + + hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 3, 3, 0, 1); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + valueExactButton = new QCheckBox(i18n("Value is exact"), mainWidget()); + hbox->addWidget(valueExactButton); + + grid->addWidget(new QLabel(i18n("Category:"), mainWidget()), 4, 0); + categoryCombo = new KComboBox(mainWidget()); + grid->addWidget(categoryCombo, 4, 1); + categoryCombo->setMaximumWidth(250); + categoryCombo->setEditable(true); + + titleLabel = new QLabel(i18n("Descriptive name:"), mainWidget()); + grid->addWidget(titleLabel, 5, 0); + titleEdit = new KLineEdit(mainWidget()); + grid->addWidget(titleEdit, 5, 1); + + connect(namesButton, SIGNAL(clicked()), this, SLOT(editNames())); + connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&))); + +} + +QalculateEditVariableDialog::~QalculateEditVariableDialog() {} + +void QalculateEditVariableDialog::slotHelp() { + KApplication::kApplication()->invokeHelp("qalculate-variable-creation"); +} + +void QalculateEditVariableDialog::slotOk() { + string str = nameEdit->text().ascii(); + remove_blank_ends(str); + if(str.empty() && (!names_edit_dialog || names_edit_dialog->isEmpty())) { + //no name -- open dialog again + nameEdit->setFocus(); + KMessageBox::error(this, i18n("Empty name field")); + return; + } + string str2 = valueEdit->text().ascii(); + remove_blank_ends(str2); + if(!(init_value && force_init_value) && str2.empty()) { + //no value -- open dialog again + valueEdit->setFocus(); + KMessageBox::error(this, i18n("Empty value field")); + return; + } + //variable with the same name exists -- overwrite or open dialog again + if((!edited_variable || !edited_variable->hasName(str)) && (!names_edit_dialog || names_edit_dialog->isEmpty()) && CALCULATOR->variableNameTaken(str, edited_variable) && KMessageBox::questionYesNo(this, i18n("An unit or variable with the same name already exists.\nDo you want to overwrite it?")) == KMessageBox::No) { + nameEdit->setFocus(); + return; + } + KnownVariable *v = edited_variable; + if(!v) { + //no need to create a new variable when a variable with the same name exists + Variable *var = CALCULATOR->getActiveVariable(str); + if(var && var->isLocal() && var->isKnown()) v = (KnownVariable*) var; + } + bool add_var = false; + if(v) { + //update existing variable + v->setLocal(true); + if(!v->isBuiltin()) { + if(force_init_value && init_value) { + v->set(*init_value); + } else { + v->set(CALCULATOR->unlocalizeExpression(valueEdit->text().ascii(), evalops.parse_options)); + v->setApproximate(!valueExactButton->isChecked()); + } + } + } else { + //new variable + if(force_init_value && init_value) { + //forced value + v = new KnownVariable("", "", *init_value, "", true); + } else { + v = new KnownVariable("", "", CALCULATOR->unlocalizeExpression(valueEdit->text().ascii(), evalops.parse_options), "", true); + v->setApproximate(!valueExactButton->isChecked()); + } + add_var = true; + } + v->setCategory(categoryCombo->lineEdit()->text().ascii()); + v->setTitle(titleEdit->text().ascii()); + if(!v->isBuiltin()) { + if(names_edit_dialog) { + names_edit_dialog->saveNames(v, str.c_str()); + } else { + if(v->countNames() == 0) { + ExpressionName ename(str); + ename.reference = true; + v->setName(ename, 1); + } else { + v->setName(str, 1); + } + } + } + if(add_var) { + CALCULATOR->addVariable(v); + } + edited_variable = v; + accept(); +} + +KnownVariable *QalculateEditVariableDialog::editVariable(QString category, KnownVariable *v, MathStructure *initial_value, bool force_value) { + + nameEdit->setFocus(); + + if(names_edit_dialog) { + delete names_edit_dialog; + names_edit_dialog = NULL; + } + edited_variable = v; + if(v) { + if(v->isLocal()) { + setCaption(i18n("Edit Variable")); + } else { + setCaption(i18n("Edit Variable (global)")); + } + } else { + setCaption(i18n("New Variable")); + } + + actionButton(Ok)->setEnabled(true); + + namesLabel->setText(""); + + //QStringList cats; + QString catstr; + categoryCombo->clear(); + tree_struct *item, *item2; + variable_cats.it = variable_cats.items.begin(); + if(variable_cats.it != variable_cats.items.end()) { + item = &*variable_cats.it; + ++variable_cats.it; + item->it = item->items.begin(); + } else { + item = NULL; + } + + catstr = ""; + while(item) { + if(!catstr.isEmpty()) catstr += "/"; + catstr += item->item.c_str(); + categoryCombo->insertItem(catstr); + while(item && item->it == item->items.end()) { + int str_i = catstr.findRev("/"); + if(str_i < 0) { + catstr = ""; + } else { + catstr.truncate(str_i); + } + item = item->parent; + } + if(item) { + item2 = &*item->it; + ++item->it; + item = item2; + item->it = item->items.begin(); + } + } + + if(initial_value && force_value) { + valueEdit->hide(); + valueLabel->hide(); + namesButton->hide(); + namesLabel->hide(); + valueExactButton->hide(); + } else { + valueEdit->show(); + valueLabel->show(); + namesButton->show(); + namesLabel->show(); + valueExactButton->show(); + } + + if(v) { + //fill in original parameters + set_name_label_and_entry(v, nameEdit, namesLabel); + valueEdit->setText(get_value_string(v->get(), false, NULL)); + nameEdit->setReadOnly(v->isBuiltin()); + valueEdit->setReadOnly(v->isBuiltin()); + valueExactButton->setEnabled(!v->isBuiltin()); + categoryCombo->lineEdit()->setText(v->category().c_str()); + titleEdit->setText(v->title(false).c_str()); + valueExactButton->setChecked(!(*printops.is_approximate) && !v->isApproximate()); + } else { + nameEdit->setReadOnly(false); + valueEdit->setReadOnly(false); + valueExactButton->setEnabled(true); + + //fill in default values + nameEdit->setText(CALCULATOR->getName().c_str()); + namesLabel->setText(""); + if(initial_value && !force_value) valueEdit->setText(get_value_string(*initial_value)); + else valueEdit->setText(""); + categoryCombo->lineEdit()->setText(category); + titleEdit->setText(""); + if(initial_value) valueExactButton->setChecked(!initial_value->isApproximate()); + else valueExactButton->setChecked(true); + if(force_value) { + valueEdit->setReadOnly(true); + valueExactButton->setEnabled(false); + } + } + + init_value = initial_value; + force_init_value = force_value; + + if(exec() == QDialog::Accepted) { + v = edited_variable; + edited_variable = NULL; + return v; + } + edited_variable = NULL; + return NULL; +} + +void QalculateEditVariableDialog::editNames() { + if(!names_edit_dialog) { + names_edit_dialog = new QalculateEditNamesDialog(TYPE_VARIABLE, this); + names_edit_dialog->setNames(edited_variable, nameEdit->text(), false); + } else { + names_edit_dialog->setNames(edited_variable, nameEdit->text(), true); + } + names_edit_dialog->exec(); + names_edit_dialog->setNamesLE(nameEdit, namesLabel); +} + +void QalculateEditVariableDialog::nameChanged(const QString &name) { + if(name.isNull()) return; + if(!CALCULATOR->variableNameIsValid(name.ascii())) { + nameEdit->blockSignals(true); + nameEdit->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str()); + nameEdit->blockSignals(false); + } +} + +#include "qalculateeditvariabledialog.moc" + diff --git a/src/qalculateeditvariabledialog.h b/src/qalculateeditvariabledialog.h new file mode 100644 index 0000000..14ccd4d --- /dev/null +++ b/src/qalculateeditvariabledialog.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEEDITVARIABLEDIALOG_H +#define QALCULATEEDITVARIABLEDIALOG_H + +#include + +class QLabel; +class KComboBox; +class KLineEdit; +class QCheckBox; +class QPushButton; +class MathStructure; +class QalculateEditNamesDialog; +class KnownVariable; +class QGridLayout; + +/** +@author Niklas Knutsson +*/ +class QalculateEditVariableDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateEditVariableDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateEditVariableDialog(); + + KnownVariable *editVariable(QString category = QString::null, KnownVariable *v = NULL, MathStructure *initial_value = NULL, bool force_value = false); + + QalculateEditNamesDialog *names_edit_dialog; + KnownVariable *edited_variable; + KComboBox *categoryCombo; + KLineEdit *valueEdit, *nameEdit, *titleEdit; + QLabel *namesLabel, *titleLabel, *nameLabel, *valueLabel; + QCheckBox *valueExactButton; + QPushButton *namesButton; + +private: + + MathStructure *init_value; + bool force_init_value; + +public slots: + + void editNames(); + void nameChanged(const QString&); + +protected slots: + + void slotHelp(); + void slotOk(); + +}; + +#endif diff --git a/src/qalculateexportcsvdialog.cpp b/src/qalculateexportcsvdialog.cpp new file mode 100644 index 0000000..93022f5 --- /dev/null +++ b/src/qalculateexportcsvdialog.cpp @@ -0,0 +1,186 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateexportcsvdialog.h" +#include "qalculate_kde_utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern MathStructure *mstruct; + +QalculateExportCSVDialog::QalculateExportCSVDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Export CSV File"), Ok | Cancel | Help, Ok, true) { + + setMainWidget(new QWidget(this)); + QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint()); + QButtonGroup *group = new QButtonGroup(); + currentResultButton = new QRadioButton(i18n("Current result"), mainWidget()); + group->insert(currentResultButton, 0); + grid->addWidget(currentResultButton, 0, 0); + currentResultButton->setChecked(true); + matrixVectorButton = new QRadioButton(i18n("Matrix/vector variable"), mainWidget()); + group->insert(matrixVectorButton, 1); + grid->addWidget(matrixVectorButton, 1, 0); + matrixVectorEdit = new KLineEdit(mainWidget()); + grid->addWidget(matrixVectorEdit, 1, 1); + grid->addWidget(new QLabel(i18n("File:"), mainWidget()), 2, 0); + fileEdit = new KURLRequester(mainWidget()); + fileEdit->setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly); + fileEdit->setCaption(i18n("Export CSV File")); + grid->addWidget(fileEdit, 2, 1); + grid->addWidget(new QLabel(i18n("Delimiter:"), mainWidget()), 3, 0); + delimiterCombo = new KComboBox(mainWidget()); + delimiterCombo->setMaximumWidth(250); + delimiterCombo->insertItem(i18n("Comma")); + delimiterCombo->insertItem(i18n("Tabulator")); + delimiterCombo->insertItem(i18n("Semicolon")); + delimiterCombo->insertItem(i18n("Space")); + delimiterCombo->insertItem(i18n("Other")); + delimiterCombo->setEditable(false); + grid->addWidget(delimiterCombo, 3, 1); + otherDelimiterEdit = new KLineEdit(mainWidget()); + grid->addWidget(otherDelimiterEdit, 4, 1); + otherDelimiterEdit->setEnabled(false); + + connect(group, SIGNAL(clicked(int)), this, SLOT(exportSourceChanged(int))); + connect(delimiterCombo, SIGNAL(activated(int)), this, SLOT(delimiterChanged(int))); + +} + +QalculateExportCSVDialog::~QalculateExportCSVDialog() {} + +void QalculateExportCSVDialog::slotHelp() { + KApplication::kApplication()->invokeHelp("qalculate-import-export-csv"); +} + +void QalculateExportCSVDialog::exportSourceChanged(int i) { + matrixVectorEdit->setEnabled(i == 1); +} +void QalculateExportCSVDialog::delimiterChanged(int i) { + otherDelimiterEdit->setEnabled(i == 4); +} +void QalculateExportCSVDialog::slotOk() { + + QString str = fileEdit->url().stripWhiteSpace(); + if(str.isEmpty()) { + //no name -- open dialog again + fileEdit->setFocus(); + KMessageBox::error(this, i18n("No file name entered.")); + return; + } + string delimiter = ""; + switch(delimiterCombo->currentItem()) { + case 0: { + delimiter = ","; + break; + } + case 1: { + delimiter = "\t"; + break; + } + case 2: { + delimiter = ";"; + break; + } + case 3: { + delimiter = " "; + break; + } + case 4: { + delimiter = otherDelimiterEdit->text().ascii(); + break; + } + } + if(delimiter.empty()) { + //no delimiter -- open dialog again + otherDelimiterEdit->setFocus(); + KMessageBox::error(this, i18n("No delimiter selected.")); + return; + } + MathStructure *matrix_struct; + if(export_variable) { + matrix_struct = (MathStructure*) &export_variable->get(); + } else if(currentResultButton->isChecked()) { + matrix_struct = mstruct; + } else { + string str2 = matrixVectorEdit->text().ascii(); + remove_blank_ends(str2); + if(str2.empty()) { + matrixVectorEdit->setFocus(); + KMessageBox::error(this, i18n("No variable name entered.")); + return; + } + Variable *var = CALCULATOR->getActiveVariable(str2); + if(!var || !var->isKnown()) { + var = CALCULATOR->getVariable(str2); + while(var && !var->isKnown()) { + var = CALCULATOR->getVariable(str2); + } + } + if(!var || !var->isKnown()) { + matrixVectorEdit->setFocus(); + KMessageBox::error(this, i18n("No known variable with entered name found.")); + return; + } + matrix_struct = (MathStructure*) &((KnownVariable*) var)->get(); + } + if(!CALCULATOR->exportCSV(*matrix_struct, str.ascii(), delimiter)) { + QString error_str; + error_str.sprintf(i18n("Could not export to file \n%s"), str.ascii()); + KMessageBox::error(this, error_str); + reject(); + } + accept(); + +} + +void QalculateExportCSVDialog::exportCSVFile(KnownVariable *v) { + + fileEdit->setFocus(); + + export_variable = v; + + if(v) { + fileEdit->setURL(v->preferredDisplayName(false, false, false, false, &can_display_unicode_string_function, (void*) fileEdit->lineEdit()).name.c_str()); + matrixVectorEdit->setText(v->preferredDisplayName(false, false, false, false, &can_display_unicode_string_function, (void*) matrixVectorEdit).name.c_str()); + matrixVectorButton->setChecked(true); + } else { + fileEdit->clear(); + matrixVectorEdit->clear(); + currentResultButton->setChecked(true); + } + currentResultButton->setEnabled(v == NULL); + matrixVectorButton->setEnabled(v == NULL); + matrixVectorEdit->setEnabled(false); + + exec(); + +} + + +#include "qalculateexportcsvdialog.moc" diff --git a/src/qalculateexportcsvdialog.h b/src/qalculateexportcsvdialog.h new file mode 100644 index 0000000..57e45f4 --- /dev/null +++ b/src/qalculateexportcsvdialog.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEEXPORTCSVDIALOG_H +#define QALCULATEEXPORTCSVDIALOG_H + +#include + +class KLineEdit; +class KComboBox; +class QRadioButton; +class KURLRequester; +class KnownVariable; + +/** +@author Niklas Knutsson +*/ +class QalculateExportCSVDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateExportCSVDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateExportCSVDialog(); + + KLineEdit *otherDelimiterEdit, *matrixVectorEdit; + KComboBox *delimiterCombo; + QRadioButton *currentResultButton, *matrixVectorButton; + KURLRequester *fileEdit; + + void exportCSVFile(KnownVariable *v = NULL); + +private: + + KnownVariable *export_variable; + +public slots: + + void exportSourceChanged(int); + void delimiterChanged(int); + +protected slots: + + void slotHelp(); + void slotOk(); + +}; + +#endif diff --git a/src/qalculateexpressionedit.cpp b/src/qalculateexpressionedit.cpp new file mode 100644 index 0000000..6ef9328 --- /dev/null +++ b/src/qalculateexpressionedit.cpp @@ -0,0 +1,1018 @@ +/*************************************************************************** + * Copyright (C) 2005. 2007 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateexpressionedit.h" + +#include "qalculate_kde_utils.h" +#include "kqalculate.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern vector modes; + +extern KQalculate *mainWin; +extern PrintOptions printops; +extern EvaluationOptions evalops; +extern bool rpn_mode, rpn_keypad_only; +extern tree_struct function_cats, unit_cats, variable_cats; +extern vector ia_units, ia_variables, ia_functions; + +class QalculateExpressionEditListBoxItem : public QListBoxItem { + +public: + + QalculateExpressionEditListBoxItem(ExpressionItem *eitem); + virtual ~QalculateExpressionEditListBoxItem(); + + int height(const QListBox*) const; + int width(const QListBox*) const; + + bool reuse(ExpressionItem *newItem); + + ExpressionItem *item; + +protected: + + void paint(QPainter*); + +private: + + QString title; + int italic_index; + bool rich_text; + +}; + +QalculateExpressionEdit::QalculateExpressionEdit(bool connected_to_main_win, QWidget *parent, const char *name) : KLineEdit(parent, name) { + + qalculateCompletionBox = new QalculateExpressionEditCompletionBox(this); + qalculateCompletion = new KCompletion(); + setCompletionObject(qalculateCompletion); + + pos_before_completion = 0; + + b_main = connected_to_main_win; + + dont_change_index = false; + expression_history_index = -1; + + setCompletionMode(KGlobalSettings::CompletionPopup); + + setKeyCompression(false); + + //check for position changes regularly + prev_position = 0; + pos_timer = startTimer(50); + + connect(qalculateCompletionBox, SIGNAL(highlighted(QListBoxItem*)), this, SLOT(insertCompletion(QListBoxItem*))); + connect(qalculateCompletionBox, SIGNAL(userCancelled(const QString&)), this, SLOT(cancelCompletion(const QString&))); + connect(this, SIGNAL(textChanged(const QString&)), this, SLOT(onTextChanged(const QString&))); + +} + +QalculateExpressionEdit::~QalculateExpressionEdit() {} + +void QalculateExpressionEdit::timerEvent(QTimerEvent *event) { + if(event->timerId() == pos_timer) { + if(cursorPosition() != prev_position) { + prev_position = cursorPosition(); + emit cursorMoved(); + } + } else { + KLineEdit::timerEvent(event); + } +} + +void QalculateExpressionEdit::onTextChanged(const QString &str) { + if(str.isEmpty()) { + if(qalculateCompletionBox) { + qalculateCompletionBox->hide(); + qalculateCompletionBox->clear(); + } + return; + } + prev_position = cursorPosition(); +} + +void QalculateExpressionEdit::cancelCompletion(const QString &str) { + int new_pos = pos_before_completion; + setText(str); + setCursorPosition(new_pos); +} + +void QalculateExpressionEdit::enableCompletion() { + setCompletionMode(KGlobalSettings::CompletionPopup); +} +void QalculateExpressionEdit::disableCompletion() { + setCompletionMode(KGlobalSettings::CompletionNone); +} +bool QalculateExpressionEdit::completionEnabled() const { + return completionMode() == KGlobalSettings::CompletionPopup; +} + +QPopupMenu *QalculateExpressionEdit::createPopupMenu() { + + setCompletionObject(NULL); + QPopupMenu *menu = KLineEdit::createPopupMenu(); + setCompletionObject(qalculateCompletion); + menu->insertSeparator(); + if(completionMode() == KGlobalSettings::CompletionPopup) menu->insertItem(i18n("Disable Completion"), this, SLOT(disableCompletion())); + else menu->insertItem(i18n("Enable Completion"), this, SLOT(enableCompletion())); + if(b_main) { + menu->insertSeparator(); + mainWin->ActionReadPrecision->plug(menu); + mainWin->ActionLimitImplicitMultiplication->plug(menu); + mainWin->ActionRPNMode->plug(menu); + QPopupMenu *modes_menu = new QPopupMenu(menu); + QObject::connect(modes_menu, SIGNAL(activated(int)), mainWin, SLOT(loadMode(int))); + for(size_t i = 0; i < modes.size(); i++) { + modes_menu->insertItem(modes[i].name, i, i); + } + modes_menu->insertSeparator(); + mainWin->ActionSaveModeAs->plug(modes_menu); + mainWin->ActionDeleteMode->plug(modes_menu); + menu->insertItem(i18n("Meta Modes"), modes_menu); + menu->insertSeparator(); + mainWin->ActionInsertMatrix->plug(menu); + mainWin->ActionInsertVector->plug(menu); + } + return menu; + +} + +#if QT_VERSION >= 0x030200 +#define GET_SELECTION int start = selectionStart(), end = -1; if(start >= 0) end = start + selectedText().length(); +#else +#define GET_SELECTION int start = -1, end = -1; getSelection(&start, &end); +#endif +#define RESTORE_SELECTION if(start > 0) setSelection(start, end - start); + +void QalculateExpressionEdit::addToHistory(const QString &str) { + for(QStringList::Iterator it = expression_history.begin(); it != expression_history.end(); ++it) { + if(*it == str) { + expression_history.erase(it); + break; + } + } + if(expression_history.size() >= 25) { + expression_history.pop_back(); + } + expression_history.insert(expression_history.begin(), str); + expression_history_index = 0; +} + + +void QalculateExpressionEdit::setAfterCompletionPosition() { + setCursorPosition(cpos_ac); +} + +void QalculateExpressionEdit::insertCompletion(QListBoxItem *li) { + + ExpressionItem *item = ((QalculateExpressionEditListBoxItem*) li)->item; + + setSelection(cstart, cend - cstart + 1); + + QString str = completed_text; + const ExpressionName *ename = NULL, *ename_r = NULL; + ename_r = &item->preferredInputName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) this); + for(size_t name_i = 0; name_i <= item->countNames() && !ename; name_i++) { + if(name_i == 0) { + ename = ename_r; + } else { + ename = &item->getName(name_i); + if(!ename || ename == ename_r || ename->plural || (ename->unicode && (!printops.use_unicode_signs || !can_display_unicode_string_function(ename->name.c_str(), (void*) this)))) { + ename = NULL; + } + } + if(ename) { + if(str.length() <= ename->name.length()) { + for(size_t i = 0; i < str.length(); i++) { + if(ename->name[i] != str[i]) { + ename = NULL; + break; + } + } + } else { + ename = NULL; + } + } + } + for(size_t name_i = 1; name_i <= item->countNames() && !ename; name_i++) { + ename = &item->getName(name_i); + if(!ename || ename == ename_r || (!ename->plural && !(ename->unicode && (!printops.use_unicode_signs || !can_display_unicode_string_function(ename->name.c_str(), (void*) this))))) { + ename = NULL; + } + if(ename) { + if(str.length() <= ename->name.length()) { + for(size_t i = 0; i < str.length(); i++) { + if(ename->name[i] != str[i]) { + ename = NULL; + break; + } + } + } else { + ename = NULL; + } + } + } + if(!ename) ename = ename_r; + if(!ename) return; + if(item->type() == TYPE_FUNCTION) { + if(text()[cend + 1] == '(') { + insert(ename->name.c_str()); + cend = cstart + ename->name.length() - 1; + cpos_ac = cend + 2; + } else { + str = ename->name.c_str(); + str += "()"; + insert(str); + cend = cstart + str.length() - 1; + cpos_ac = cend; + } + } else { + insert(ename->name.c_str()); + cend = cstart + ename->name.length() - 1; + cpos_ac = cend + 1; + } + setCursorPosition(cpos_ac); + +} + +bool matchesExpressionItem(const QString &str, ExpressionItem *item) { + bool b_match = false; + for(size_t name_i = 1; !b_match && name_i <= item->countNames(); name_i++) { + const ExpressionName *ename = &item->getName(name_i); + if(ename && str.length() <= ename->name.length()) { + b_match = true; + for(size_t i = 0; i < str.length(); i++) { + if(ename->name[i] != str[i]) { + b_match = false; + break; + } + } + } + } + return b_match; +} + +void QalculateExpressionEdit::makeCompletion(const QString &str) { + if(cursorPosition() <= 0 || str.isEmpty()) { + if(qalculateCompletionBox) { + qalculateCompletionBox->hide(); + qalculateCompletionBox->clear(); + } + return; + } + uint start = (uint) cursorPosition(); + cend = (int) start - 1; + QString str2 = str; + str2.truncate(start); + const char *cstr = str2.ascii(); + bool non_number_before = false; + size_t cpos = strlen(cstr) - 1; + start--; + while(true) { + while(cpos > 0 && (unsigned char) cstr[cpos] >= 0x80 && (unsigned char) cstr[cpos] <= 0xBF) { + cpos--; + } + if(!CALCULATOR->utf8_pos_is_valid_in_name((char*) &cstr[cpos])) { + start++; + break; + } else if(is_in(NUMBERS, cstr[cpos])) { + if(non_number_before) { + start++; + break; + } + } else { + non_number_before = true; + } + if(start == 0 || cpos == 0) break; + start--; + cpos--; + } + if(start >= (uint) cursorPosition()) { + if(qalculateCompletionBox) { + qalculateCompletionBox->hide(); + qalculateCompletionBox->clear(); + } + return; + } + cstart = (int) start; + str2.remove(0, start); + + completed_text = str2; + pos_before_completion = cursorPosition(); + qalculateCompletionBox->setCancelledText(text()); + + matched_items.clear(); + if(evalops.parse_options.functions_enabled) { + for(size_t i = 0; i < CALCULATOR->functions.size(); i++) { + if(CALCULATOR->functions[i]->isActive()) { + if(matchesExpressionItem(str2, CALCULATOR->functions[i])) { + matched_items.push_back(CALCULATOR->functions[i]); + } + } + } + } + if(evalops.parse_options.variables_enabled) { + for(size_t i = 0; i < CALCULATOR->variables.size(); i++) { + if(CALCULATOR->variables[i]->isActive()) { + if(matchesExpressionItem(str2, CALCULATOR->variables[i])) { + matched_items.push_back(CALCULATOR->variables[i]); + } + } + } + } + if(evalops.parse_options.units_enabled) { + for(size_t i = 0; i < CALCULATOR->units.size(); i++) { + if(CALCULATOR->units[i]->isActive() && CALCULATOR->units[i]->subtype() != SUBTYPE_COMPOSITE_UNIT) { + if(matchesExpressionItem(str2, CALCULATOR->units[i])) { + matched_items.push_back(CALCULATOR->units[i]); + } + } + } + } + + if(matched_items.isEmpty()) { + if(qalculateCompletionBox) { + qalculateCompletionBox->hide(); + qalculateCompletionBox->clear(); + } + } else { + setCompletedItems(); + } +} + +void QalculateExpressionEdit::updateCompletion() { +} + +void QalculateExpressionEdit::wrapSelection() { + GET_SELECTION + if(start >= 0) { + deselect(); + setCursorPosition(start); + insert("("); + setCursorPosition(end + 1); + insert(")"); + setSelection(start, end - start + 2); + } +} + +void QalculateExpressionEdit::keyPressEvent(QKeyEvent *e) { + if(e->key() == Key_Enter || e->key() == Key_Return) { + if(b_main) { + mainWin->execute(); + e->accept(); + return; + } else { + return KLineEdit::keyPressEvent(e); + } + } + if(e->state() & ControlButton && e->key() == Key_Asterisk) { + if(rpn_mode && b_main && (!rpn_keypad_only || e->state() & Keypad)) { + mainWin->calculateRPN(OPERATION_RAISE); + return; + } + insert("^"); + e->accept(); + return; + } + if(e->state() != 0 && e->state() != ShiftButton && e->state() != Keypad) { + KLineEdit::keyPressEvent(e); + return; + } + switch(e->key()) { + case Key_Period: { + if(e->state() == Keypad) { + insert(CALCULATOR->getDecimalPoint()); + e->accept(); + return; + } + break; + } + case Key_Comma: { + if(e->state() == Keypad) { + insert(CALCULATOR->getDecimalPoint()); + e->accept(); + return; + } + break; + } + case Key_AsciiCircum: { + if(rpn_mode && b_main && (!rpn_keypad_only || e->state() & Keypad)) { + mainWin->calculateRPN(OPERATION_RAISE); + return; + } + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + insert("^"); + e->accept(); + return; + } + case Key_Slash: { + if(rpn_mode && b_main && (!rpn_keypad_only || e->state() & Keypad)) { + mainWin->calculateRPN(OPERATION_DIVIDE); + return; + } + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + if(printops.use_unicode_signs && printops.division_sign == DIVISION_SIGN_DIVISION && can_display_unicode_string_function(SIGN_DIVISION, (void*) this)) { + insert(SIGN_DIVISION); + e->accept(); + return; + } + break; + } + case Key_Asterisk: { + if(rpn_mode && b_main && (!rpn_keypad_only || e->state() & Keypad)) { + mainWin->calculateRPN(OPERATION_MULTIPLY); + return; + } + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_DOT && can_display_unicode_string_function(SIGN_MULTIDOT, (void*) this)) { + insert(SIGN_MULTIDOT); + } else if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_DOT && can_display_unicode_string_function(SIGN_SMALLCIRCLE, (void*) this)) { + insert(SIGN_SMALLCIRCLE); + } else if(printops.use_unicode_signs && printops.multiplication_sign == MULTIPLICATION_SIGN_X && can_display_unicode_string_function(SIGN_MULTIPLICATION, (void*) this)) { + insert(SIGN_MULTIPLICATION); + } else { + insert("*"); + } + e->accept(); + return; + } + case Key_Plus: { + if(rpn_mode && b_main && (!rpn_keypad_only || e->state() & Keypad)) { + mainWin->calculateRPN(OPERATION_ADD); + return; + } + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + e->accept(); + break; + } + case Key_Minus: { + if(rpn_mode && b_main && (!rpn_keypad_only || e->state() & Keypad)) { + mainWin->calculateRPN(OPERATION_SUBTRACT); + return; + } + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + if(printops.use_unicode_signs && can_display_unicode_string_function(SIGN_MINUS, (void*) this)) { + insert(SIGN_MINUS); + e->accept(); + return; + } + break; + } + case Key_Up: {} + case Key_PageUp: { + if(expression_history_index + 1 < (int) expression_history.size()) { + expression_history_index++; + dont_change_index = true; + setText(expression_history[expression_history_index]); + dont_change_index = false; + } + e->accept(); + return; + } + case Key_Down: {} + case Key_PageDown: { + if(expression_history_index > -1) { + expression_history_index--; + dont_change_index = true; + if(expression_history_index < 0) { + clear(); + } else { + setText(expression_history[expression_history_index]); + } + dont_change_index = false; + } + e->accept(); + return; + } + case Key_BraceLeft: {} + case Key_BraceRight: { + return; + } + case 0xffff: { + if(e->text().utf8() == "⁰") { + insert("°"); + e->accept(); + return; + } + if(e->text().utf8() == "¹") { + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + insert("^1"); + e->accept(); + return; + } + if(e->text().utf8() == "²") { + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + insert("^2"); + e->accept(); + return; + } + if(e->text().utf8() == "³") { + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + insert("^3"); + e->accept(); + return; + } + if(e->text().utf8() == "⁴") { + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + insert("^4"); + e->accept(); + return; + } + if(e->text().utf8() == "⁵") { + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + insert("^5"); + e->accept(); + return; + } + if(e->text().utf8() == "⁶") { + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + insert("^6"); + e->accept(); + return; + } + if(e->text().utf8() == "⁷") { + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + insert("^7"); + e->accept(); + return; + } + if(e->text().utf8() == "⁸") { + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + insert("^8"); + e->accept(); + return; + } + if(e->text().utf8() == "⁹") { + if(!evalops.parse_options.rpn) { + wrapSelection(); + deselect(); + } + insert("^9"); + e->accept(); + return; + } + break; + } + } + KLineEdit::keyPressEvent(e); +} + +bool QalculateExpressionEdit::eventFilter(QObject *o, QEvent *ev) { + if(o == this && ev->type() == QEvent::KeyPress) { + QKeyEvent *e = static_cast(ev); + if((e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter) && qalculateCompletionBox && qalculateCompletionBox->isVisible()) { + if(qalculateCompletionBox->selectedItem()) { + KCursor::autoHideEventFilter(this, ev); + e->accept(); + qalculateCompletionBox->hide(); + deselect(); + return true; + } else { + qalculateCompletionBox->hide(); + return false; + } + } + } + return KLineEdit::eventFilter(o, ev); +} + + +void set_title(ExpressionItem *item, QString &title) { + if(item->type() != TYPE_VARIABLE || !item->title(false).empty()) { + title = item->title().c_str(); + } else { + Variable *v = (Variable*) item; + if(is_answer_variable(v)) { + title = i18n("a previous result"); + } else if(v->isKnown()) { + if(((KnownVariable*) v)->isExpression()) { + title = CALCULATOR->localizeExpression(((KnownVariable*) v)->expression()).c_str(); + } else { + if(((KnownVariable*) v)->get().isMatrix()) { + title = i18n("matrix"); + } else if(((KnownVariable*) v)->get().isVector()) { + title = i18n("vector"); + } else { + title = CALCULATOR->printMathStructureTimeOut(((KnownVariable*) v)->get(), 30).c_str(); + } + } + } else { + if(((UnknownVariable*) v)->assumptions()) { + switch(((UnknownVariable*) v)->assumptions()->sign()) { + case ASSUMPTION_SIGN_POSITIVE: { + title = i18n("positive"); + break; + } + case ASSUMPTION_SIGN_NONPOSITIVE: { + title = i18n("non-positive"); + break; + } + case ASSUMPTION_SIGN_NEGATIVE: { + title = i18n("negative"); + break; + } + case ASSUMPTION_SIGN_NONNEGATIVE: { + title = i18n("non-negative"); + break; + } + case ASSUMPTION_SIGN_NONZERO: { + title = i18n("non-zero"); + break; + } + default: {} + } + if(!title.isEmpty() && !((UnknownVariable*) v)->assumptions()->type() == ASSUMPTION_TYPE_NONE) title += " "; + switch(((UnknownVariable*) v)->assumptions()->type()) { + case ASSUMPTION_TYPE_INTEGER: { + title += i18n("integer"); + break; + } + case ASSUMPTION_TYPE_RATIONAL: { + title += i18n("rational"); + break; + } + case ASSUMPTION_TYPE_REAL: { + title += i18n("real"); + break; + } + case ASSUMPTION_TYPE_COMPLEX: { + title += i18n("complex"); + break; + } + case ASSUMPTION_TYPE_NUMBER: { + title += i18n("number"); + break; + } + case ASSUMPTION_TYPE_NONMATRIX: { + title += i18n("(not matrix)"); + break; + } + default: {} + } + if(title.isEmpty()) title = i18n("unknown"); + } else { + title = i18n("default assumptions"); + } + } + } +} + +string sub_suffix(const ExpressionName *ename) { + size_t i = ename->name.rfind('_'); + bool b = i == string::npos || i == ename->name.length() - 1 || i == 0; + size_t i2 = 1; + string str; + if(b) { + if(is_in(NUMBERS, ename->name[ename->name.length() - 1])) { + while(ename->name.length() > i2 + 1 && is_in(NUMBERS, ename->name[ename->name.length() - 1 - i2])) { + i2++; + } + } + str += ename->name.substr(0, ename->name.length() - i2); + } else { + str += ename->name.substr(0, i); + } + str += ""; + if(b) str += ename->name.substr(ename->name.length() - i2, i2); + else str += ename->name.substr(i + 1, ename->name.length() - (i + 1)); + str += ""; + return str; +} + +QString makeListName(ExpressionItem *item, QWidget *w, int *italic_index, bool *rich_text) { + string str; + const ExpressionName *ename, *ename_r; + *rich_text = false; + bool b = false; + ename_r = &item->preferredInputName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) w); + if(ename_r->suffix && ename_r->name.length() > 1) { + str = sub_suffix(ename_r); + *rich_text = true; + } else { + str = ename_r->name; + } + if(item->type() == TYPE_FUNCTION) str += "()"; + for(size_t name_i = 1; name_i <= item->countNames(); name_i++) { + ename = &item->getName(name_i); + if(ename && ename != ename_r && !ename->plural && (!ename->unicode || can_display_unicode_string_function(ename->name.c_str(), (void*) w))) { + str += " "; + if(!b) { + *italic_index = str.length(); + *rich_text = true; + str += ""; + b = true; + } + if(ename->suffix && ename->name.length() > 1) { + str += sub_suffix(ename); + } else { + str += ename->name; + } + if(item->type() == TYPE_FUNCTION) str += "()"; + } + } + if(b) str += ""; + return str.c_str(); +} + +QalculateExpressionEditListBoxItem::QalculateExpressionEditListBoxItem(ExpressionItem *eitem) : QListBoxItem() { + item = eitem; + italic_index = -1; + setText(makeListName(item, listBox(), &italic_index, &rich_text)); + set_title(item, title); +} +QalculateExpressionEditListBoxItem::~QalculateExpressionEditListBoxItem() { +} + +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 +QString rPixelSqueeze(const QString& name, const QFontMetrics& fontMetrics, uint maxPixels) +{ + uint nameWidth = fontMetrics.width(name); + + if (maxPixels < nameWidth) + { + QString tmp = name; + const uint em = fontMetrics.maxWidth(); + maxPixels -= fontMetrics.width("..."); + + while (maxPixels < nameWidth && !tmp.isEmpty()) + { + int length = tmp.length(); + int delta = em ? (nameWidth - maxPixels) / em : length; + + if(delta < 1) delta = 1; + else if(length < delta) delta = length; + + tmp.remove(length - delta, delta); + nameWidth = fontMetrics.width(tmp); + } + + return (tmp + "..."); + } + + return name; +} +#endif + +void QalculateExpressionEditListBoxItem::paint(QPainter *painter) { + + int itemHeight = height(listBox()); + + int entryWidth = listBox()->width() - listBox()->style().pixelMetric(QStyle::PM_ScrollBarExtent) - 2 * listBox()->style().pixelMetric(QStyle::PM_DefaultFrameWidth); + int titleWidth = (entryWidth / 2) - 1; + int nameWidth = entryWidth - titleWidth - 2; + + if(!text().isEmpty()) { + QString squeezedText; + if(rich_text) { + QSimpleRichText rt(text(), painter->font()); + rt.setWidth(entryWidth); + if(rt.widthUsed() > nameWidth - 1) { + squeezedText = text(); + if(italic_index > 0) squeezedText.truncate(italic_index); +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + squeezedText = rPixelSqueeze(squeezedText, listBox()->fontMetrics(), nameWidth); +#else + squeezedText = KStringHandler::rPixelSqueeze(squeezedText, listBox()->fontMetrics(), nameWidth); +#endif + painter->drawText(0, 0, nameWidth, itemHeight, Qt::AlignLeft | Qt::AlignVCenter, squeezedText); + } else { + QColorGroup cg = listBox()->colorGroup(); + cg.setColor(QColorGroup::Text, painter->pen().color()); + rt.draw(painter, 1, 0, QRect(0, 0, nameWidth - 1, itemHeight), cg, &painter->brush()); + } + } else { +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + squeezedText = rPixelSqueeze(text(), listBox()->fontMetrics(), nameWidth); +#else + squeezedText = KStringHandler::rPixelSqueeze(text(), listBox()->fontMetrics(), nameWidth); +#endif + painter->drawText(0, 0, nameWidth, itemHeight, Qt::AlignLeft | Qt::AlignVCenter, squeezedText); + } +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + squeezedText = rPixelSqueeze(title, listBox()->fontMetrics(), titleWidth); +#else + squeezedText = KStringHandler::rPixelSqueeze(title, listBox()->fontMetrics(), titleWidth); +#endif + QFont font = painter->font(); + font.setItalic(true); + painter->setFont(font); + painter->drawText(entryWidth - titleWidth, 0, titleWidth, itemHeight, Qt::AlignLeft | Qt::AlignVCenter, squeezedText); + } + +} + +int QalculateExpressionEditListBoxItem::height(const QListBox *lb) const { + int h; + h = lb->fontMetrics().lineSpacing() + 4; + return QMAX(h, QApplication::globalStrut().height()); +} + +int QalculateExpressionEditListBoxItem::width(const QListBox *lb) const { + return QMAX(lb->fontMetrics().width(text()) + 6, QApplication::globalStrut().width()); +} +bool QalculateExpressionEditListBoxItem::reuse(ExpressionItem *newItem) { + if(item == newItem) return false; + item = newItem; + italic_index = -1; + setText(makeListName(item, listBox(), &italic_index, &rich_text)); + set_title(item, title); + return true; +} + +QalculateExpressionEditCompletionBox::QalculateExpressionEditCompletionBox(QWidget *parent, const char *name) : KCompletionBox(parent, name) { +} +QalculateExpressionEditCompletionBox::~QalculateExpressionEditCompletionBox() { +} + +void QalculateExpressionEditCompletionBox::setItems(const QValueVector& items) { + + bool block = signalsBlocked(); + blockSignals(true); + + QListBoxItem* item = firstItem(); + if(!item) { + insertItemList(items); + } else { + //Keep track of whether we need to change anything, + //so we can avoid a repaint for identical updates, + //to reduce flicker + bool dirty = false; + +#if QT_VERSION >= 0x030200 + QValueVector::ConstIterator it = items.constBegin(); + const QValueVector::ConstIterator itEnd = items.constEnd(); +#else + QValueVector::ConstIterator it = items.begin(); + const QValueVector::ConstIterator itEnd = items.end(); +#endif + + for (; it != itEnd; ++it) { + if(item) { + const bool changed = ((QalculateExpressionEditListBoxItem*) item)->reuse(*it); + dirty = dirty || changed; + item = item->next(); + } else { + dirty = true; + //Inserting an item is a way of making this dirty + insertItem(new QalculateExpressionEditListBoxItem(*it)); + } + } + + //If there is an unused item, mark as dirty -> less items now + if(item) dirty = true; + + QListBoxItem* tmp = item; + while((item = tmp)) { + tmp = item->next(); + delete item; + } + + if(dirty) triggerUpdate(false); + } + sort(); + + if(isVisible() && size().height() != sizeHint().height()) { +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + hide(); + popup(); +#else + sizeAndPosition(); +#endif + } + + blockSignals(block); + + // Trigger d->down_workaround = true within KCompletionBox + QStringList dummy; + KCompletionBox::insertItems(dummy, 1); + +} + +void QalculateExpressionEditCompletionBox::insertItemList(const QValueVector & list, int index) { + if(index < 0) index = count(); + for(QValueVector::ConstIterator it = list.begin(); it != list.end(); ++it) { + insertItem(new QalculateExpressionEditListBoxItem(*it), index++); + } +} + +void QalculateExpressionEdit::setCompletedItems() { + + QString txt; + if(qalculateCompletionBox && qalculateCompletionBox->isVisible()) { + // The popup is visible already - do the matching on the initial string, + // not on the currently selected one. + txt = qalculateCompletionBox->cancelledText(); + } else { + txt = text(); + } + + if(!matched_items.isEmpty() && !(matched_items.size() == 1 && matched_items[0]->hasName(txt.ascii()))) { + + if(qalculateCompletionBox->isVisible()) { + bool wasSelected = qalculateCompletionBox->isSelected(qalculateCompletionBox->currentItem()); + const QString currentSelection = qalculateCompletionBox->currentText(); + qalculateCompletionBox->setItems(matched_items); + QListBoxItem* item = qalculateCompletionBox->findItem(currentSelection, Qt::ExactMatch); + // If no item is selected, that means the listbox hasn't been manipulated by the user yet, + // because it's not possible otherwise to have no selected item. In such case make + // always the first item current and unselected, so that the current item doesn't jump. + if(!item || !wasSelected) { + wasSelected = false; + item = qalculateCompletionBox->item(0); + } + if(item) { + qalculateCompletionBox->blockSignals(true); + qalculateCompletionBox->setCurrentItem(item); + qalculateCompletionBox->setSelected(item, wasSelected); + qalculateCompletionBox->blockSignals(false); + } + } else { // completion box not visible yet -> show it + if(!txt.isEmpty()) qalculateCompletionBox->setCancelledText(txt); + ((QalculateExpressionEditCompletionBox*) qalculateCompletionBox)->setItems(matched_items); + qalculateCompletionBox->popup(); + } + + } else { + + if(qalculateCompletionBox && qalculateCompletionBox->isVisible()) { + qalculateCompletionBox->hide(); + } + + } + +} + +void QalculateExpressionEditCompletionBox::hideEvent(QHideEvent*) { + emit hidden(); +} + +#include "qalculateexpressionedit.moc" diff --git a/src/qalculateexpressionedit.h b/src/qalculateexpressionedit.h new file mode 100644 index 0000000..7434489 --- /dev/null +++ b/src/qalculateexpressionedit.h @@ -0,0 +1,109 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEEXPRESSIONEDIT_H +#define QALCULATEEXPRESSIONEDIT_H + +#include +#include +#include +#include + +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 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& list, int index = -1); + +public slots: + + void setItems(const QValueVector& items); + +protected: + + void hideEvent(QHideEvent*); + +signals: + + void hidden(); + +}; + + +#endif diff --git a/src/qalculatefunctionsdialog.cpp b/src/qalculatefunctionsdialog.cpp new file mode 100644 index 0000000..80b452d --- /dev/null +++ b/src/qalculatefunctionsdialog.cpp @@ -0,0 +1,537 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculatefunctionsdialog.h" +#include "qalculate_kde_utils.h" +#include "qalculateeditfunctiondialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern tree_struct function_cats; +extern vector 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 += ""; + str += ename->name.c_str(); + str += ""; + 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 += "
"; + str += f->getName(i2).name.c_str(); + } + } + str += "
"; + str += "
"; + if(f->subtype() == SUBTYPE_DATA_SET) { + str += "
"; + 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("<", "<"); + str2.replace(">", ">"); + str += str2; + str += "
"; + } + if(!f->description().empty()) { + str += "
"; + str2 = f->description().c_str(); + str2.replace("<", "<"); + str2.replace(">", ">"); + str += str2; + str += "
"; + } + if(f->subtype() == SUBTYPE_DATA_SET && !((DataSet*) f)->copyright().empty()) { + str += "
"; + str2 = ((DataSet*) f)->copyright().c_str(); + str2.replace("<", "<"); + str2.replace(">", ">"); + str += str2; + str += "
"; + } + if(iargs) { + str += "
"; + str += i18n("Arguments"); + str += "
"; + 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 += ": "; + if(arg) { + str2= arg->printlong().c_str(); + } else { + str2= default_arg.printlong().c_str(); + } + str2.replace("<", "<"); + str2.replace(">", ">"); + 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 += "
"; + } + } + if(!f->condition().empty()) { + str += "
"; + str += i18n("Requirement"); + str += ": "; + str2 = f->printCondition().c_str(); + str2.replace("<", "<"); + str2.replace(">", ">"); + str += str2; + str += "
"; + } + if(f->subtype() == SUBTYPE_DATA_SET) { + DataSet *ds = (DataSet*) f; + str += "
"; + str += i18n("Properties"); + str += "
"; + DataPropertyIter it; + DataProperty *dp = ds->getFirstProperty(&it); + while(dp) { + if(!dp->isHidden()) { + if(!dp->title(false).empty()) { + str2 = dp->title().c_str(); + str2.replace("<", "<"); + str2.replace(">", ">"); + 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 += "
"; + if(!dp->description().empty()) { + str += ""; + str2 = dp->description().c_str(); + str2.replace("<", "<"); + str2.replace(">", ">"); + str += str2; + str += "
"; + } + } + dp = ds->getNextProperty(&it); + } + } + str.replace("\n", "
"); + descriptionBrowser->setText(str); + } else { + editButton->setEnabled(false); + insertButton->setEnabled(false); + applyButton->setEnabled(false); + deleteButton->setEnabled(false); + deactivateButton->setEnabled(false); + selected_function = NULL; + descriptionBrowser->clear(); + } +} + +void QalculateFunctionsDialog::addFunctionTreeItem(MathFunction *f) { + QListViewItem *i = new KListViewItem(functionView, f->title(true).c_str()); + functionItems[i] = f; + if(f == selected_function) { + functionView->setSelected(i, true); + } +} + + +void QalculateFunctionsDialog::categorySelected() { + QListViewItem *selected = categoryView->selectedItem(); + bool no_cat = false, b_all = false, b_inactive = false; + functionView->clear(); + functionItems.clear(); + if(!selected) { + selected_category = ""; + functionSelected(); + return; + } + selected_category = categoryItems[selected]; + if(selected_category == i18n("All")) { + b_all = true; + } else if(selected_category == i18n("Uncategorized")) { + no_cat = true; + } else if(selected_category == i18n("Inactive")) { + b_inactive = true; + } + if(!b_all && !no_cat && !b_inactive && selected_category[0] == '/') { + string str = selected_category.ascii(); + str.erase(str.begin()); + for(size_t i = 0; i < CALCULATOR->functions.size(); i++) { + if(CALCULATOR->functions[i]->isActive() && CALCULATOR->functions[i]->category().substr(0, selected_category.length() - 1) == str) { + addFunctionTreeItem(CALCULATOR->functions[i]); + } + } + } else { + string str = selected_category.ascii(); + for(size_t i = 0; i < CALCULATOR->functions.size(); i++) { + if((b_inactive && !CALCULATOR->functions[i]->isActive()) || (CALCULATOR->functions[i]->isActive() && (b_all || (no_cat && CALCULATOR->functions[i]->category().empty()) || (!b_inactive && CALCULATOR->functions[i]->category() == str)))) { + addFunctionTreeItem(CALCULATOR->functions[i]); + } + } + } + if(!selected_function || !functionView->selectedItem()) { + QListViewItemIterator it(functionView); + if(it.current()) + functionView->setSelected(it.current(), true); + } + +} + + +#include "qalculatefunctionsdialog.moc" diff --git a/src/qalculatefunctionsdialog.h b/src/qalculatefunctionsdialog.h new file mode 100644 index 0000000..7a0104f --- /dev/null +++ b/src/qalculatefunctionsdialog.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEFUNCTIONSDIALOG_H +#define QALCULATEFUNCTIONSDIALOG_H + +#include +#include + +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 functionItems; + QMap categoryItems; + + KListView *categoryView; + KListView *functionView; + QPushButton *newButton; + QPushButton *editButton; + QPushButton *deleteButton; + QPushButton *deactivateButton; + QPushButton *insertButton; + QPushButton *applyButton; + QPushButton *helpButton; + QPushButton *buttonClose; + KTextBrowser *descriptionBrowser; + +public slots: + + void updateFunctionTree(); + void functionDoubleClicked(QListViewItem*); + void functionSelected(); + void categorySelected(); + void insertFunction(); + void applyFunction(); + void deactivateFunction(); + void deleteFunction(); + void editFunction(); + void newFunction(); + +protected slots: + + void slotHelp(); + +signals: + + void functionsChanged(); + void insertRequest(MathFunction*); + void applyRequest(MathFunction*); + +}; + +#endif diff --git a/src/qalculateimportcsvdialog.cpp b/src/qalculateimportcsvdialog.cpp new file mode 100644 index 0000000..88f8044 --- /dev/null +++ b/src/qalculateimportcsvdialog.cpp @@ -0,0 +1,216 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateimportcsvdialog.h" +#include "qalculate_kde_utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern tree_struct variable_cats; + +QalculateImportCSVDialog::QalculateImportCSVDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Import CSV File"), Ok | Cancel | Help, Ok, true) { + + setMainWidget(new QWidget(this)); + QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint()); + grid->addWidget(new QLabel(i18n("File:"), mainWidget()), 0, 0); + fileEdit = new KURLRequester(mainWidget()); + fileEdit->setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly); + fileEdit->setCaption(i18n("Import CSV File")); + grid->addWidget(fileEdit, 0, 1); + grid->addWidget(new QLabel(i18n("Import as:"), mainWidget()), 1, 0); + QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addLayout(hbox, 1, 1); + QButtonGroup *group = new QButtonGroup(); + matrixButton = new QRadioButton(i18n("Matrix"), mainWidget()); + group->insert(matrixButton, 0); + hbox->addWidget(matrixButton); + matrixButton->setChecked(true); + vectorsButton = new QRadioButton(i18n("Vectors"), mainWidget()); + group->insert(vectorsButton, 1); + hbox->addWidget(vectorsButton); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + grid->addWidget(new QLabel(i18n("Name:"), mainWidget()), 2, 0); + nameEdit = new KLineEdit(mainWidget()); + grid->addWidget(nameEdit, 2, 1); + grid->addWidget(new QLabel(i18n("Descriptive name:"), mainWidget()), 3, 0); + titleEdit = new KLineEdit(mainWidget()); + grid->addWidget(titleEdit, 3, 1); + grid->addWidget(new QLabel(i18n("Category:"), mainWidget()), 4, 0); + categoryCombo = new KComboBox(mainWidget()); + categoryCombo->setMaximumWidth(250); + categoryCombo->setEditable(true); + grid->addWidget(categoryCombo, 4, 1); + grid->addWidget(new QLabel(i18n("First row:"), mainWidget()), 5, 0); + firstRowBox = new QSpinBox(1, 1000, 1, mainWidget()); + grid->addWidget(firstRowBox, 5, 1); + hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 6, 6, 0, 1); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + includesHeadingsButton = new QCheckBox(i18n("Includes headings"), mainWidget()); + includesHeadingsButton->setChecked(true); + hbox->addWidget(includesHeadingsButton); + grid->addWidget(new QLabel(i18n("Delimiter:"), mainWidget()), 7, 0); + delimiterCombo = new KComboBox(mainWidget()); + delimiterCombo->setMaximumWidth(250); + delimiterCombo->insertItem(i18n("Comma")); + delimiterCombo->insertItem(i18n("Tabulator")); + delimiterCombo->insertItem(i18n("Semicolon")); + delimiterCombo->insertItem(i18n("Space")); + delimiterCombo->insertItem(i18n("Other")); + delimiterCombo->setEditable(false); + grid->addWidget(delimiterCombo, 7, 1); + otherDelimiterEdit = new KLineEdit(mainWidget()); + grid->addWidget(otherDelimiterEdit, 8, 1); + otherDelimiterEdit->setEnabled(false); + + connect(delimiterCombo, SIGNAL(activated(int)), this, SLOT(delimiterChanged(int))); + connect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(nameChanged(const QString&))); + +} + +QalculateImportCSVDialog::~QalculateImportCSVDialog() { +} + +void QalculateImportCSVDialog::slotHelp() { + KApplication::kApplication()->invokeHelp("qalculate-import-export-csv"); +} + +void QalculateImportCSVDialog::delimiterChanged(int i) { + otherDelimiterEdit->setEnabled(i == 4); +} + +void QalculateImportCSVDialog::slotOk() { + + QString str = fileEdit->url().stripWhiteSpace(); + if(str.isEmpty()) { + //no name -- open dialog again + fileEdit->setFocus(); + KMessageBox::error(this, i18n("No file name entered.")); + return; + } + string delimiter = ""; + switch(delimiterCombo->currentItem()) { + case 0: { + delimiter = ","; + break; + } + case 1: { + delimiter = "\t"; + break; + } + case 2: { + delimiter = ";"; + break; + } + case 3: { + delimiter = " "; + break; + } + case 4: { + delimiter = otherDelimiterEdit->text().ascii(); + break; + } + } + if(delimiter.empty()) { + //no delimiter -- open dialog again + otherDelimiterEdit->setFocus(); + KMessageBox::error(this, i18n("No delimiter selected.")); + return; + } + if(!CALCULATOR->importCSV(str.ascii(), firstRowBox->value(), includesHeadingsButton->isChecked(), delimiter, matrixButton->isChecked(), nameEdit->text().ascii(), titleEdit->text().ascii(), categoryCombo->lineEdit()->text().ascii())) { + KMessageBox::error(this, i18n("An error occured when importing the CSV file.")); + reject(); + } + accept(); + +} + +bool QalculateImportCSVDialog::importCSVFile() { + + fileEdit->setFocus(); + + nameEdit->clear(); + fileEdit->clear(); + titleEdit->clear(); + + //QStringList cats; + QString catstr; + categoryCombo->clear(); + tree_struct *item, *item2; + variable_cats.it = variable_cats.items.begin(); + if(variable_cats.it != variable_cats.items.end()) { + item = &*variable_cats.it; + ++variable_cats.it; + item->it = item->items.begin(); + } else { + item = NULL; + } + + catstr = ""; + while(item) { + if(!catstr.isEmpty()) catstr += "/"; + catstr += item->item.c_str(); + categoryCombo->insertItem(catstr); + while(item && item->it == item->items.end()) { + int str_i = catstr.findRev("/"); + if(str_i < 0) { + catstr = ""; + } else { + catstr.truncate(str_i); + } + item = item->parent; + } + if(item) { + item2 = &*item->it; + ++item->it; + item = item2; + item->it = item->items.begin(); + } + } + + categoryCombo->lineEdit()->clear(); + + if(exec() == QDialog::Accepted) { + return true; + } + return false; +} + +void QalculateImportCSVDialog::nameChanged(const QString &name) { + if(name.isNull()) return; + if(!CALCULATOR->variableNameIsValid(name.ascii())) { + nameEdit->blockSignals(true); + nameEdit->setText(CALCULATOR->convertToValidVariableName(name.ascii()).c_str()); + nameEdit->blockSignals(false); + } +} + +#include "qalculateimportcsvdialog.moc" diff --git a/src/qalculateimportcsvdialog.h b/src/qalculateimportcsvdialog.h new file mode 100644 index 0000000..8b6e96e --- /dev/null +++ b/src/qalculateimportcsvdialog.h @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEIMPORTCSVDIALOG_H +#define QALCULATEIMPORTCSVDIALOG_H + +#include + +class KLineEdit; +class KComboBox; +class QSpinBox; +class QCheckBox; +class QRadioButton; +class KURLRequester; + +/** +@author Niklas Knutsson +*/ +class QalculateImportCSVDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateImportCSVDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateImportCSVDialog(); + + KLineEdit *nameEdit, *titleEdit, *otherDelimiterEdit; + KComboBox *categoryCombo, *delimiterCombo; + QSpinBox *firstRowBox; + QCheckBox *includesHeadingsButton; + QRadioButton *matrixButton, *vectorsButton; + KURLRequester *fileEdit; + + bool importCSVFile(); + +public slots: + + void delimiterChanged(int); + void nameChanged(const QString&); + +protected slots: + + void slotHelp(); + void slotOk(); + +}; + +#endif diff --git a/src/qalculateinsertfunctiondialog.cpp b/src/qalculateinsertfunctiondialog.cpp new file mode 100644 index 0000000..c0fc808 --- /dev/null +++ b/src/qalculateinsertfunctiondialog.cpp @@ -0,0 +1,404 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateinsertfunctiondialog.h" +#include "qalculate_kde_utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 = ""; + titlestr += mathFunction->title(true).c_str(); + titlestr += ""; + 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("<", "<"); + str.replace(">", ">"); + str.replace("\n", "
"); + KActiveLabel *descrLabel = new KActiveLabel(str, box); + descrLabel->setAlignment(Qt::AlignJustify); + enableButtonSeparator(true); + } +} + +QalculateInsertFunctionDialog::~QalculateInsertFunctionDialog() { +} + +QString QalculateInsertFunctionDialog::functionExpression() { + QString str = mathFunction->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionWidget).name.c_str(), str2; + str += "("; + int args = 0; + if(mathFunction->args() > 0) { + args = mathFunction->args(); + } else if(mathFunction->minargs() > 0) { + args = mathFunction->minargs() + 1; + } else { + args = 1; + } + for(int i = 0; i < args; i++) { + if(mathFunction->getArgumentDefinition(i + 1) && mathFunction->getArgumentDefinition(i + 1)->type() == ARGUMENT_TYPE_BOOLEAN) { + if(((QButtonGroup*) entry[i])->id(((QButtonGroup*) entry[i])->selected()) == 1) { + str2 = "1"; + } else { + str2 = "0"; + } + } else if(mathFunction->getArgumentDefinition(i + 1) && mathFunction->getArgumentDefinition(i + 1)->type() == ARGUMENT_TYPE_INTEGER) { + str2 = ((QSpinBox*) entry[i])->text(); + } else if(mathFunction->subtype() == SUBTYPE_DATA_SET && mathFunction->getArgumentDefinition(i + 1) && mathFunction->getArgumentDefinition(i + 1)->type() == ARGUMENT_TYPE_DATA_PROPERTY) { + int index = ((KComboBox*) entry[i])->currentItem(); + DataPropertyIter it; + DataSet *ds = (DataSet*) mathFunction; + DataProperty *dp = ds->getFirstProperty(&it); + while(dp) { + if(!dp->isHidden()) { + if(index <= 0) break; + index--; + } + dp = ds->getNextProperty(&it); + } + if(dp) { + str2 = dp->getName().c_str(); + } else { + str2 = "info"; + } + } else { + str2 = ((KLineEdit*) entry[i])->text(); + } + //if the minimum number of function arguments have been filled, do not add anymore if entry is empty + if(i >= mathFunction->minargs()) { + str2 = str2.stripWhiteSpace(); + } + if((i < mathFunction->minargs() || !str2.isEmpty()) && mathFunction->getArgumentDefinition(i + 1) && (mathFunction->getArgumentDefinition(i + 1)->suggestsQuotes() || (mathFunction->getArgumentDefinition(i + 1)->type() == ARGUMENT_TYPE_TEXT && str2.find(CALCULATOR->getComma().c_str()) >= 0))) { + if(str2.length() < 1 || (str2[0] != '\"' && str[0] != '\'')) { + str2.insert(0, "\""); + str2 += "\""; + } + } + if(i > 0) { + str += CALCULATOR->getComma().c_str(); + str += " "; + } + str += str2; + } + str += ")"; + return str; +} + +void QalculateInsertFunctionDialog::slotOk() { + accept(); +} + +void QalculateInsertFunctionDialog::slotApply() { + done(100); +} + +void QalculateInsertFunctionDialog::selectDate(int index) { + KDialogBase *dialog = new KDialogBase(this, 0, true, i18n("Date"), Ok|Cancel); + KDatePicker *datePicker; + QDate date(QDate::fromString(((KLineEdit*) entry[index])->text(), Qt::ISODate)); + if(date.isValid()) datePicker = new KDatePicker(dialog->makeVBoxMainWidget(), date); + else datePicker = new KDatePicker(dialog->makeVBoxMainWidget()); + if(dialog->exec() == QDialog::Accepted) { + ((KLineEdit*) entry[index])->setText(datePicker->date().toString(Qt::ISODate)); + } + dialog->deleteLater(); +} +void QalculateInsertFunctionDialog::selectFile(int index) { + QString filename = KFileDialog::getSaveFileName(((KLineEdit*) entry[index])->text(), QString::null, this, i18n("File")); + if(!filename.isEmpty()) { + ((KLineEdit*) entry[index])->setText(filename); + } +} +void QalculateInsertFunctionDialog::insertMatrix(int index) { + QalculateInsertMatrixVectorDialog *d = new QalculateInsertMatrixVectorDialog(this); + QString str = ((KLineEdit*) entry[index])->text(); + MathStructure mstruct; + if(!str.isEmpty()) { + CALCULATOR->parse(&mstruct, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options)); + } + if(mstruct.isVector()) { + str = d->editMatrixVector(&mstruct, false); + } else { + str = d->editMatrixVector(NULL, false); + } + if(!str.isEmpty()) { + ((KLineEdit*) entry[index])->setText(str); + } + d->deleteLater(); +} +void QalculateInsertFunctionDialog::insertVector(int index) { + QalculateInsertMatrixVectorDialog *d = new QalculateInsertMatrixVectorDialog(this); + QString str = ((KLineEdit*) entry[index])->text(); + MathStructure mstruct; + if(!str.isEmpty()) { + CALCULATOR->parse(&mstruct, CALCULATOR->unlocalizeExpression(str.ascii(), evalops.parse_options)); + } + if(mstruct.isVector()) { + str = d->editMatrixVector(&mstruct, true); + } else { + str = d->editMatrixVector(NULL, true); + } + if(!str.isEmpty()) { + ((KLineEdit*) entry[index])->setText(str); + } + d->deleteLater(); +} + +#include "qalculateinsertfunctiondialog.moc" diff --git a/src/qalculateinsertfunctiondialog.h b/src/qalculateinsertfunctiondialog.h new file mode 100644 index 0000000..5954196 --- /dev/null +++ b/src/qalculateinsertfunctiondialog.h @@ -0,0 +1,56 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEINSERTFUNCTIONDIALOG_H +#define QALCULATEINSERTFUNCTIONDIALOG_H + +#include +#include + +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 label; + QValueVector entry; + QValueVector type_label; + +protected slots: + + void slotOk(); + void slotApply(); + + void selectDate(int); + void selectFile(int); + void insertMatrix(int); + void insertVector(int); + +}; + +#endif diff --git a/src/qalculateinsertmatrixvectordialog.cpp b/src/qalculateinsertmatrixvectordialog.cpp new file mode 100644 index 0000000..6e6f994 --- /dev/null +++ b/src/qalculateinsertmatrixvectordialog.cpp @@ -0,0 +1,381 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateinsertmatrixvectordialog.h" +#include "qalculate_kde_utils.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern PrintOptions printops; + +class QalculateInsertMatrixTableItem : public QTableItem { + +public: + + QalculateInsertMatrixTableItem(QTable *table); + QalculateInsertMatrixTableItem(QTable *table, const QString & text); + + int alignment() const; + +}; + +class QalculateInsertMatrixTable : public QTable { + + public: + + QalculateInsertMatrixTable(QWidget *parent = 0, const char *name = 0) : QTable(parent, name) {} + QalculateInsertMatrixTable(int numRows, int numCols, QWidget *parent = 0, const char *name = 0) : QTable(numRows, numCols, parent, name) {} + + QWidget *beginEdit(int row, int col, bool replace) { + QWidget *w = QTable::beginEdit(row, col, replace); + ((QLineEdit*) w)->selectAll(); + return w; + } + +}; + + +QalculateInsertMatrixVectorDialog::QalculateInsertMatrixVectorDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Edit Variable"), Ok | Cancel | User1, Ok, true, KGuiItem(i18n("Insert Selection"))) { + + setMainWidget(new QWidget(this)); + QGridLayout *grid = new QGridLayout(mainWidget(), 1, 1, 0, spacingHint()); + grid->addWidget(new QLabel(i18n("Rows:"), mainWidget()), 0, 0); + rowsBox = new QSpinBox(1, 1000, 1, mainWidget()); + grid->addWidget(rowsBox, 0, 1); + grid->addWidget(new QLabel(i18n("Columns:"), mainWidget()), 1, 0); + columnsBox = new QSpinBox(1, 1000, 1, mainWidget()); + grid->addWidget(columnsBox, 1, 1); + QHBoxLayout *hbox = new QHBoxLayout(0, 0, spacingHint()); + grid->addMultiCellLayout(hbox, 2, 2, 0, 1); + hbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum)); + QButtonGroup *group = new QButtonGroup(); + matrixButton = new QRadioButton(i18n("Matrix"), mainWidget()); + group->insert(matrixButton, 0); + hbox->addWidget(matrixButton); + vectorButton = new QRadioButton(i18n("Vector"), mainWidget()); + group->insert(vectorButton, 1); + hbox->addWidget(vectorButton); + elementsLabel = new QLabel(i18n("Elements:"), mainWidget()); + grid->addMultiCellWidget(elementsLabel, 3, 3, 0, 1); + elementsTable = new QalculateInsertMatrixTable(0, 0, mainWidget()); + grid->addMultiCellWidget(elementsTable, 4, 4, 0, 1); + elementsTable->setSelectionMode(QTable::Single); + + insertSelectionButton = actionButton(User1); + onSelectionChanged(); + + connect(insertSelectionButton, SIGNAL(clicked()), this, SLOT(insertSelection())); + connect(elementsTable, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); + connect(rowsBox, SIGNAL(valueChanged(int)), this, SLOT(rowsChanged(int))); + connect(columnsBox, SIGNAL(valueChanged(int)), this, SLOT(columnsChanged(int))); + connect(group, SIGNAL(clicked(int)), this, SLOT(typeChanged(int))); + +} + +QalculateInsertMatrixVectorDialog::~QalculateInsertMatrixVectorDialog() {} + +void QalculateInsertMatrixVectorDialog::onSelectionChanged() { + insertSelectionButton->setEnabled(elementsTable->currentSelection() >= 0); +} +void QalculateInsertMatrixVectorDialog::typeChanged(int i) { + if(i == 0) { + elementsLabel->setText(i18n("Elements:")); + bool b = true; + for(int index_r = elementsTable->numRows() - 1; index_r >= 0 && b; index_r--) { + for(int index_c = elementsTable->numCols() - 1; index_c >= 0; index_c--) { + if(elementsTable->text(index_r, index_c).isEmpty()) { + elementsTable->setText(index_r, index_c, "0"); + } else { + b = false; + break; + } + } + } + } else { + elementsLabel->setText(i18n("Elements (in horizontal order):")); + } +} +void QalculateInsertMatrixVectorDialog::rowsChanged(int i) { + int r = elementsTable->numRows(); + elementsTable->setNumRows(i); + bool b = matrixButton->isChecked(); + for(int index_r = r; index_r < i; index_r++) { + for(int index_c = 0; index_c < elementsTable->numCols(); index_c++) { + if(b) elementsTable->setItem(index_r, index_c, new QalculateInsertMatrixTableItem(elementsTable, "0")); + else elementsTable->setItem(index_r, index_c, new QalculateInsertMatrixTableItem(elementsTable)); + } + } +} +void QalculateInsertMatrixVectorDialog::columnsChanged(int i) { + int c = elementsTable->numCols(); + elementsTable->setNumCols(i); + bool b = matrixButton->isChecked(); + for(int index_r = 0; index_r < elementsTable->numRows(); index_r++) { + for(int index_c = c; index_c < i; index_c++) { + if(b) elementsTable->setItem(index_r, index_c, new QalculateInsertMatrixTableItem(elementsTable, "0")); + else elementsTable->setItem(index_r, index_c, new QalculateInsertMatrixTableItem(elementsTable)); + } + } +} + +QString QalculateInsertMatrixVectorDialog::newVector() { + return editMatrixVector(NULL, true); +} +QString QalculateInsertMatrixVectorDialog::newMatrix() { + return editMatrixVector(NULL, false); +} + +void QalculateInsertMatrixVectorDialog::slotOk() { + int r = rowsBox->value(); + int c = columnsBox->value(); + if(vectorButton->isChecked()) { + bool b = false; + matrixstr = "["; + for(int index_r = 0; index_r < r; index_r++) { + for(int index_c = 0; index_c < c; index_c++) { + if(!elementsTable->text(index_r, index_c).isEmpty()) { + QString str2 = elementsTable->text(index_r, index_c).stripWhiteSpace(); + if(!str2.isEmpty()) { + if(b) { + matrixstr += CALCULATOR->getComma(); + matrixstr += " "; + } else { + b = true; + } + matrixstr += str2; + } + } + } + } + matrixstr += "]"; + } else { + matrixstr = "["; + bool b1 = false; + for(int index_r = 0; index_r < r; index_r++) { + if(b1) { + matrixstr += CALCULATOR->getComma(); + matrixstr += " "; + } else { + b1 = true; + } + matrixstr += "["; + bool b2 = false; + for(int index_c = 0; index_c < c; index_c++) { + if(b2) { + matrixstr += CALCULATOR->getComma(); + matrixstr += " "; + } else { + b2 = true; + } + matrixstr += elementsTable->text(index_r, index_c).stripWhiteSpace(); + } + matrixstr += "]"; + } + matrixstr += "]"; + } + accept(); +} +void QalculateInsertMatrixVectorDialog::insertSelection() { + QTableSelection sel = elementsTable->selection(elementsTable->currentSelection()); + if(vectorButton->isChecked()) { + bool b = false; + matrixstr = "["; + for(int index_r = sel.topRow(); index_r <= sel.bottomRow(); index_r++) { + for(int index_c = sel.leftCol(); index_c <= sel.rightCol(); index_c++) { + if(!elementsTable->text(index_r, index_c).isEmpty()) { + QString str2 = elementsTable->text(index_r, index_c).stripWhiteSpace(); + if(!str2.isEmpty()) { + if(b) { + matrixstr += CALCULATOR->getComma(); + matrixstr += " "; + } else { + b = true; + } + matrixstr += str2; + } + } + } + } + matrixstr += "]"; + } else { + matrixstr = "["; + bool b1 = false; + for(int index_r = sel.topRow(); index_r <= sel.bottomRow(); index_r++) { + if(b1) { + matrixstr += CALCULATOR->getComma(); + matrixstr += " "; + } else { + b1 = true; + } + matrixstr += "["; + bool b2 = false; + for(int index_c = sel.leftCol(); index_c <= sel.rightCol(); index_c++) { + if(b2) { + matrixstr += CALCULATOR->getComma(); + matrixstr += " "; + } else { + b2 = true; + } + matrixstr += elementsTable->text(index_r, index_c).stripWhiteSpace(); + } + matrixstr += "]"; + } + matrixstr += "]"; + } + accept(); +} + +QString QalculateInsertMatrixVectorDialog::editMatrixVector(const MathStructure *initial_value, bool create_vector, bool is_text_struct, bool is_result) { + + if(initial_value && !initial_value->isVector()) { + return NULL; + } + + if(initial_value) { + create_vector = !initial_value->isMatrix(); + } + if(create_vector) { + vectorButton->setChecked(true); + elementsLabel->setText(i18n("Elements (in horizontal order):")); + } else { + matrixButton->setChecked(true); + elementsLabel->setText(i18n("Elements:")); + } + + if(is_result) { +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + setButtonOKText(i18n("Insert")); + setButtonCancelText(KStdGuiItem::close().text()); +#else +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 3 + setButtonOK(KGuiItem(i18n("Insert"))); +#else + setButtonOK(KStdGuiItem::insert()); +#endif + setButtonCancel(KStdGuiItem::close()); +#endif + actionButton(Cancel)->setDefault(true); + actionButton(Cancel)->setFocus(); + if(create_vector) { + setCaption(i18n("Vector Result")); + } else { + setCaption(i18n("Matrix Result")); + } + } else { +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + setButtonOKText(KStdGuiItem::ok().text()); + setButtonCancelText(KStdGuiItem::cancel().text()); +#else + setButtonOK(KStdGuiItem::ok()); + setButtonCancel(KStdGuiItem::cancel()); +#endif + actionButton(Ok)->setDefault(true); + elementsTable->setFocus(); + if(create_vector) { + setCaption(i18n("Vector")); + } else { + setCaption(i18n("Matrix")); + } + } + + int r = 4, c = 4; + if(create_vector) { + if(initial_value) { + r = initial_value->countChildren(); + c = (int) ::sqrt(r) + 4; + if(r % c > 0) { + r = r / c + 1; + } else { + r = r / c; + } + } else { + c = 4; + r = 4; + } + } else if(initial_value) { + c = initial_value->columns(); + r = initial_value->rows(); + } + + rowsBox->setValue(r); + columnsBox->setValue(c); + elementsTable->setNumRows(r); + elementsTable->setNumCols(c); + + int timeout; + if(initial_value) timeout = 3000 / (r * c); + else timeout = 3000; + printops.can_display_unicode_string_arg = (void*) elementsTable; + for(int index_r = 0; index_r < r; index_r++) { + for(int index_c = 0; index_c < c; index_c++) { + if(create_vector) { + if(initial_value && index_r * c + index_c < (int) initial_value->countChildren()) { + if(is_text_struct) elementsTable->setText(index_r, index_c, initial_value->getChild(index_r * c + index_c + 1)->symbol().c_str()); + else elementsTable->setText(index_r, index_c, initial_value->getChild(index_r * c + index_c + 1)->print(printops).c_str()); + } else { + elementsTable->setText(index_r, index_c, ""); + } + } else { + if(initial_value) { + if(is_text_struct) elementsTable->setText(index_r, index_c, initial_value->getElement(index_r + 1, index_c + 1)->symbol().c_str()); + else elementsTable->setText(index_r, index_c, initial_value->getElement(index_r + 1, index_c + 1)->print(printops).c_str()); + } else { + elementsTable->setText(index_r, index_c, "0"); + } + } + } + } + printops.can_display_unicode_string_arg = NULL; + matrixstr = ""; + + onSelectionChanged(); + + exec(); + + return matrixstr; +} + +#if QT_VERSION >= 0x030200 +QalculateInsertMatrixTableItem::QalculateInsertMatrixTableItem(QTable *table) : QTableItem(table, QTableItem::OnTyping) {} +#else +QalculateInsertMatrixTableItem::QalculateInsertMatrixTableItem(QTable *table) : QTableItem(table, QTableItem::OnTyping, QString::null) {} +#endif +QalculateInsertMatrixTableItem::QalculateInsertMatrixTableItem(QTable *table, const QString & text) : QTableItem(table, QTableItem::OnTyping, text) {} + +int QalculateInsertMatrixTableItem::alignment() const {return Qt::AlignRight;} + +#include "qalculateinsertmatrixvectordialog.moc" + diff --git a/src/qalculateinsertmatrixvectordialog.h b/src/qalculateinsertmatrixvectordialog.h new file mode 100644 index 0000000..32ba4ea --- /dev/null +++ b/src/qalculateinsertmatrixvectordialog.h @@ -0,0 +1,73 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEINSERTMATRIXVECTORDIALOG_H +#define QALCULATEINSERTMATRIXVECTORDIALOG_H + +#include + +class QTable; +class QLabel; +class QSpinBox; +class QRadioButton; +class KComboBox; +class KLineEdit; +class QPushButton; +class MathStructure; +class QalculateEditNamesDialog; +class KnownVariable; + +/** +@author Niklas Knutsson +*/ +class QalculateInsertMatrixVectorDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateInsertMatrixVectorDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateInsertMatrixVectorDialog(); + + QString newMatrix(); + QString newVector(); + QString editMatrixVector(const MathStructure *initial_value = NULL, bool create_vector = false, bool is_text_struct = false, bool is_result = false); + + QLabel *elementsLabel; + QRadioButton *matrixButton, *vectorButton; + QTable *elementsTable; + QSpinBox *rowsBox, *columnsBox; + QString matrixstr; + QPushButton *insertSelectionButton; + +public slots: + + void typeChanged(int); + void rowsChanged(int); + void columnsChanged(int); + void onSelectionChanged(); + +protected slots: + + void slotOk(); + void insertSelection(); + +}; + +#endif diff --git a/src/qalculateperiodictabledialog.cpp b/src/qalculateperiodictabledialog.cpp new file mode 100644 index 0000000..1eb07be --- /dev/null +++ b/src/qalculateperiodictabledialog.cpp @@ -0,0 +1,276 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateperiodictabledialog.h" +#include "qalculate_kde_utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "qalculatebuttonwithdata.h" +#include +#include +#include +#include + +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 = "
"; str += e->getProperty(p_number).c_str(); str += "
"; + new KActiveLabel(str, vbox2); + str = ""; str += e->getProperty(p_symbol).c_str(); str += ""; + new KActiveLabel(str, vbox2); + str = ""; str += e->getProperty(p_name).c_str(); str += " "; + 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 = ""; str += i18n("Classification"); str += ":"; str += ""; + 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 = ""; str += dp->title().c_str(); str += ":"; str += ""; + new QLabel(str, grid); + new KActiveLabel(sval, grid); + button = new QalculateButtonWithData((void*) dp, QIconSet(SmallIcon("editpaste")), "", grid); + QObject::connect(button, SIGNAL(clickedWithData(void*)), SLOT(insertElementData(void*))); + } + } + dp = ds->getNextProperty(&it); + } +} +QalculateElementInfoDialog::~QalculateElementInfoDialog() {} + +void QalculateElementInfoDialog::insertElementData(void *data) { + DataProperty *dp = (DataProperty*) data; + DataSet *ds = dp->parentSet(); + if(ds) { + QString str = ds->preferredInputName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) expressionWidget).name.c_str(); + str += "("; + str += e->getProperty(ds->getPrimaryKeyProperty()).c_str(); + str += CALCULATOR->getComma().c_str(); + str += " "; + str += dp->getName().c_str(); + str += ")"; + insert_text_in_expression(str); + } +} + + +#include "qalculateperiodictabledialog.moc" diff --git a/src/qalculateperiodictabledialog.h b/src/qalculateperiodictabledialog.h new file mode 100644 index 0000000..5d52767 --- /dev/null +++ b/src/qalculateperiodictabledialog.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEPERIODICTABLEDIALOG_H +#define QALCULATEPERIODICTABLEDIALOG_H + +#include +#include + +class QGridLayout; +class DataObject; + +/** +@author Niklas Knutsson +*/ +class QalculatePeriodicTableDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculatePeriodicTableDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculatePeriodicTableDialog(); + + QGridLayout *grid; + +public slots: + + void showElementInfo(void*); + +}; + +class QalculateElementInfoDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateElementInfoDialog(DataObject *element, QWidget *parent = 0, const char *name = 0); + virtual ~QalculateElementInfoDialog(); + + DataObject *e; + +public slots: + + void insertElementData(void*); + +}; + +#endif diff --git a/src/qalculateplotdialog.cpp b/src/qalculateplotdialog.cpp new file mode 100644 index 0000000..e1adbae --- /dev/null +++ b/src/qalculateplotdialog.cpp @@ -0,0 +1,789 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateplotdialog.h" +#include "qalculateexpressionedit.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 +#include +#else +#include +#endif +#include +#include +#include + +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 &y_vectors, vector &x_vectors, vector &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 y_vectors; + vector x_vectors; + vector 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 y_vectors; + vector x_vectors; + vector pdps; + PlotParameters pp; + if(!generatePlot(pp, y_vectors, x_vectors, pdps)) { + CALCULATOR->closeGnuplot(); + actionButton(User1)->setEnabled(false); + return; + } + CALCULATOR->plotVectors(&pp, y_vectors, x_vectors, pdps); + actionButton(User1)->setEnabled(true); + for(size_t i = 0; i < pdps.size(); i++) { + if(pdps[i]) delete pdps[i]; + } +} +void QalculatePlotDialog::generatePlotSeries(MathStructure **x_vector, MathStructure **y_vector, int type, string str, string str_x) { + EvaluationOptions eo; + eo.approximation = APPROXIMATION_APPROXIMATE; + eo.parse_options = evalops.parse_options; + eo.parse_options.read_precision = DONT_READ_PRECISION; + if(type == 1 || type == 2) { + *y_vector = new MathStructure(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(str, evalops.parse_options), eo)); + *x_vector = NULL; + } else { + MathStructure min(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(minEdit->text().ascii(), evalops.parse_options), eo)); + MathStructure max(CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(maxEdit->text().ascii(), evalops.parse_options), eo)); + *x_vector = new MathStructure(); + (*x_vector)->clearVector(); + if(stepSizeButton->isChecked()) { + *y_vector = new MathStructure(CALCULATOR->expressionToPlotVector(str, min, max, CALCULATOR->calculate(CALCULATOR->unlocalizeExpression(stepSizeEdit->text().ascii(), evalops.parse_options), eo), *x_vector, str_x, evalops.parse_options)); + } else { + *y_vector = new MathStructure(CALCULATOR->expressionToPlotVector(str, min, max, samplingRateBox->value(), *x_vector, str_x, evalops.parse_options)); + } + } +} + +#include "qalculateplotdialog.moc" diff --git a/src/qalculateplotdialog.h b/src/qalculateplotdialog.h new file mode 100644 index 0000000..984dad6 --- /dev/null +++ b/src/qalculateplotdialog.h @@ -0,0 +1,101 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEPLOTDIALOG_H +#define QALCULATEPLOTDIALOG_H + +#include +#include +#include + +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 &y_vectors, vector &x_vectors, vector &pdps); + void generatePlotSeries(MathStructure **x_vector, MathStructure **y_vector, int type, string str, string str_x); + + QMap itemStyle; + QMap itemSmoothing; + QMap itemType; + QMap itemAxis; + QMap itemRows; + QMap itemXVector; + QMap itemYVector; + QMap itemXVariable; + +protected slots: + + void slotHelp(); + +public slots: + + void onClosing(); + void seriesItemRenamed(QListViewItem*, const QString&, int); + void seriesSelected(); + void rangeTypeChanged(int); + void typeChanged(int); + void savePlot(); + void expressionActivated(); + void addSeries(); + void modifySeries(); + void removeSeries(); + void applyRange(); + void applyAppearance(); + void updatePlot(); + void saveMode(); + +}; + +#endif diff --git a/src/qalculateprecisiondialog.cpp b/src/qalculateprecisiondialog.cpp new file mode 100644 index 0000000..d1f6741 --- /dev/null +++ b/src/qalculateprecisiondialog.cpp @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateprecisiondialog.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +QalculatePrecisionDialog::QalculatePrecisionDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, false, i18n("Precision"), Apply | Close, Close, true) { + +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + setButtonApplyText(i18n("Recalculate")); +#else + setButtonApply(KGuiItem(i18n("Recalculate"))); +#endif + setMainWidget(new QWidget(this)); + QHBoxLayout *box = new QHBoxLayout(mainWidget()); + box->setSpacing(spacingHint()); + box->addWidget(new QLabel(i18n("Precision:"), mainWidget())); + precisionBox = new QSpinBox(1, 100000, 1, mainWidget()); + precisionBox->setButtonSymbols(QSpinBox::PlusMinus); + box->addWidget(precisionBox); + + resize(QSize(300, minimumSizeHint().height()).expandedTo(minimumSizeHint())); + +} + + +QalculatePrecisionDialog::~QalculatePrecisionDialog() {} + + +#include "qalculateprecisiondialog.moc" diff --git a/src/qalculateprecisiondialog.h b/src/qalculateprecisiondialog.h new file mode 100644 index 0000000..9abc99c --- /dev/null +++ b/src/qalculateprecisiondialog.h @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEPRECISIONDIALOG_H +#define QALCULATEPRECISIONDIALOG_H + +#include + +class QSpinBox; + +/** +@author Niklas Knutsson +*/ +class QalculatePrecisionDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculatePrecisionDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculatePrecisionDialog(); + + QSpinBox *precisionBox; + +}; + +#endif diff --git a/src/qalculatepreferencesdialog.cpp b/src/qalculatepreferencesdialog.cpp new file mode 100644 index 0000000..a0faeff --- /dev/null +++ b/src/qalculatepreferencesdialog.cpp @@ -0,0 +1,414 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculatepreferencesdialog.h" +#include "qalculate_kde_utils.h" + +#include +#include +#include +#include +#include +#include +#include +#if KDE_VERSION_MAJOR > 3 || KDE_VERSION_MINOR > 1 +#include +#endif +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 +#include +#else +#include +#endif +#include +#include +#include +#include +#include +#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 + +class KFontRequester : public QWidget +{ + Q_OBJECT + + public: + + KFontRequester( QWidget *parent=0L, const char *name=0L, + bool onlyFixed=false ); + + QFont font() const { return m_selFont; } + virtual void setFont( const QFont &font, bool onlyFixed=false ); + + protected: + + void displaySampleText(); + + protected slots: + + virtual void buttonClicked(); + + protected: + + bool m_onlyFixed; + QString m_sampleText, m_title; + QLabel *m_sampleLabel; + QPushButton *m_button; + QFont m_selFont; + +}; + + +KFontRequester::KFontRequester( QWidget *parent, const char *name, + bool onlyFixed ) : QWidget( parent, name ), + m_onlyFixed( onlyFixed ) +{ + QHBoxLayout *layout = new QHBoxLayout( this, 0, KDialog::spacingHint() ); + + m_sampleLabel = new QLabel( this, "m_sampleLabel" ); + m_button = new QPushButton( i18n( "Choose..." ), this, "m_button" ); + + m_sampleLabel->setFrameStyle( QFrame::StyledPanel | QFrame::Sunken ); + setFocusProxy( m_button ); + + layout->addWidget( m_sampleLabel, 1 ); + layout->addWidget( m_button ); + + connect( m_button, SIGNAL( clicked() ), SLOT( buttonClicked() ) ); + + displaySampleText(); + +} + +void KFontRequester::setFont( const QFont &font, bool onlyFixed ) +{ + m_selFont = font; + m_onlyFixed = onlyFixed; + + displaySampleText(); +} +void KFontRequester::buttonClicked() +{ + int result = KFontDialog::getFont( m_selFont, m_onlyFixed, parentWidget() ); + + if ( result == KDialog::Accepted ) + { + displaySampleText(); + } +} + +void KFontRequester::displaySampleText() +{ + m_sampleLabel->setFont( m_selFont ); + + int size = m_selFont.pointSize(); + if(size == -1) + size = m_selFont.pixelSize(); + + if ( m_sampleText.isEmpty() ) + m_sampleLabel->setText( QString( "%1 %2" ).arg( m_selFont.family() ) + .arg( size ) ); + else + m_sampleLabel->setText( m_sampleText ); +} +#endif + +QalculatePreferencesDialog::QalculatePreferencesDialog(QWidget *parent, const char *name) : KDialogBase(parent, name, true, i18n("Preferences"), Ok | Apply | Cancel, Ok, false) { + +#if KDE_VERSION_MAJOR < 4 && KDE_VERSION_MINOR < 2 + QTabWidget *tabs = new QTabWidget(this); +#else + QTabWidget *tabs = new KTabWidget(this); +#endif + setMainWidget(tabs); + QWidget *page1 = new QWidget(this); + QWidget *page2 = new QWidget(this); + tabs->addTab(page1, i18n("General")); + tabs->addTab(page2, i18n("Fonts")); + + QVBoxLayout *vbox = new QVBoxLayout(page1, spacingHint()); + systrayButton = new QCheckBox(i18n("Close to system tray"), page1); + QToolTip::add(systrayButton, i18n("If the application will reside in the system tray when the window is closed")); + vbox->addWidget(systrayButton); + statusButton = new QCheckBox(i18n("Display expression status"), page1); + QToolTip::add(statusButton, i18n("If as-you-type expression status shall be displayed below the expression entry")); + vbox->addWidget(statusButton); + iconsButton = new QCheckBox(i18n("Use icon buttons"), page1); + QToolTip::add(iconsButton, i18n("Use icons instead of text on the top-right buttons. The third state uses the style setting for icons on buttons.")); + iconsButton->setTristate(true); + vbox->addWidget(iconsButton); + fetchExchangeRatesButton = new QCheckBox(i18n("Update exchange rates on start"), page1); + QToolTip::add(fetchExchangeRatesButton, i18n("If current exchange rates shall be downloaded from the internet at program start")); + vbox->addWidget(fetchExchangeRatesButton); + saveModeButton = new QCheckBox(i18n("Save mode on exit"), page1); + QToolTip::add(saveModeButton, i18n("If the mode of the calculator shall be restored")); + vbox->addWidget(saveModeButton); + saveDefsButton = new QCheckBox(i18n("Save definitions on exit"), page1); + QToolTip::add(saveDefsButton, i18n("If changes to functions, units and variables shall be saved automatically")); + vbox->addWidget(saveDefsButton); + rpnKeypadOnlyButton = new QCheckBox(i18n("Use only keypad keys for RPN"), page1); + QToolTip::add(rpnKeypadOnlyButton, i18n("Use only keypad keys for RPN operations (+-*/^) and use the rest of the keyboard for expression entry")); + vbox->addWidget(rpnKeypadOnlyButton); + dotAsSeparatorButton = new QCheckBox(i18n("Ignores dots in numbers"), page1); + QToolTip::add(dotAsSeparatorButton, i18n("Allow dots, '.', to be used as thousands separator instead of as an alternative to decimal sign")); + if(CALCULATOR->getDecimalPoint() == ".") dotAsSeparatorButton->hide(); + vbox->addWidget(dotAsSeparatorButton); + unicodeButton = new QCheckBox(i18n("Enable unicode signs"), page1); + QToolTip::add(unicodeButton, i18n("Disable this if you have problems with some fancy characters")); + vbox->addWidget(unicodeButton); + lowerCaseButton = new QCheckBox(i18n("Use lower case in numbers"), page1); + QToolTip::add(lowerCaseButton, i18n("If lower case letters should be used in numbers with non-decimal base")); + vbox->addWidget(lowerCaseButton); + lowerCaseEButton = new QCheckBox(i18n("Use lower case \"e\""), page1); + QToolTip::add(lowerCaseEButton, i18n("If \"e\"; shall be used instead of \"E\" in numbers")); + vbox->addWidget(lowerCaseEButton); + alternativeBasePrefixButton = new QCheckBox(i18n("Alternative base prefixes"), page1); + QToolTip::add(alternativeBasePrefixButton, i18n("If hexadecimal numbers shall be displayed with \"0x0\" and binary numbers with \"0b00\" as prefixes")); + vbox->addWidget(alternativeBasePrefixButton); + spellOutLogicalOperatorsButton = new QCheckBox(i18n("Spell out logical operators"), page1); + QToolTip::add(spellOutLogicalOperatorsButton, i18n("If logical and/or shall be displayed as \"&&\"/\"||\" or \"and\"/\"or\"")); + vbox->addWidget(spellOutLogicalOperatorsButton); + QGridLayout *grid = new QGridLayout(vbox); + multiplicationLabel = new QLabel(i18n("Multiplication sign:"), page1); + grid->addWidget(multiplicationLabel, 0, 0); + QButtonGroup *group = new QButtonGroup(); + dotButton = new QRadioButton(SIGN_MULTIDOT, page1); + group->insert(dotButton, 0); + grid->addWidget(dotButton, 0, 1); + exButton = new QRadioButton(SIGN_MULTIPLICATION, page1); + group->insert(exButton, 1); + grid->addWidget(exButton, 0, 2); + asteriskButton = new QRadioButton("*", page1); + group->insert(asteriskButton, 2); + grid->addWidget(asteriskButton, 0, 3); + divisionLabel = new QLabel(i18n("Division sign:"), page1); + grid->addWidget(divisionLabel, 1, 0); + group = new QButtonGroup(); + divisionSlashButton = new QRadioButton(" " SIGN_DIVISION_SLASH " ", page1); + group->insert(divisionSlashButton, 0); + grid->addWidget(divisionSlashButton, 1, 1); + divisionButton = new QRadioButton(SIGN_DIVISION, page1); + group->insert(divisionButton, 1); + grid->addWidget(divisionButton, 1, 2); + slashButton = new QRadioButton("/", page1); + group->insert(slashButton, 2); + grid->addWidget(slashButton, 1, 3); + vbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + vbox = new QVBoxLayout(page2, spacingHint()); + useCustomResultFontButton = new QCheckBox(i18n("Custom result font"), page2); + vbox->addWidget(useCustomResultFontButton); + resultFontEdit = new KFontRequester(page2); + vbox->addWidget(resultFontEdit); + useCustomExpressionFontButton = new QCheckBox(i18n("Custom expression font"), page2); + vbox->addWidget(useCustomExpressionFontButton); + expressionFontEdit = new KFontRequester(page2); + vbox->addWidget(expressionFontEdit); + useCustomStatusFontButton = new QCheckBox(i18n("Custom status font"), page2); + vbox->addWidget(useCustomStatusFontButton); + statusFontEdit = new KFontRequester(page2); + vbox->addWidget(statusFontEdit); + grid = new QGridLayout(vbox); + grid->addWidget(new QLabel(i18n("Status error color:"), page2), 0, 0); +#if KDE_VERSION_MAJOR == 3 && KDE_VERSION_MINOR < 1 + statusErrorColorButton = new KColorButton(page2); +#else + statusErrorColorButton = new KColorButton("red", "red", page2); +#endif + grid->addWidget(statusErrorColorButton, 0, 1); + grid->addWidget(new QLabel(i18n("Status warning color:"), page2), 1, 0); +#if KDE_VERSION_MAJOR == 3 && KDE_VERSION_MINOR < 1 + statusWarningColorButton = new KColorButton(page2); +#else + statusWarningColorButton = new KColorButton("blue", "blue", page2); +#endif + grid->addWidget(statusWarningColorButton, 1, 1); + vbox->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + + + connect(useCustomResultFontButton, SIGNAL(toggled(bool)), resultFontEdit, SLOT(setEnabled(bool))); + connect(useCustomExpressionFontButton, SIGNAL(toggled(bool)), expressionFontEdit, SLOT(setEnabled(bool))); + connect(useCustomStatusFontButton, SIGNAL(toggled(bool)), statusFontEdit, SLOT(setEnabled(bool))); + connect(unicodeButton, SIGNAL(toggled(bool)), multiplicationLabel, SLOT(setEnabled(bool))); + connect(unicodeButton, SIGNAL(toggled(bool)), dotButton, SLOT(setEnabled(bool))); + connect(unicodeButton, SIGNAL(toggled(bool)), exButton, SLOT(setEnabled(bool))); + connect(unicodeButton, SIGNAL(toggled(bool)), asteriskButton, SLOT(setEnabled(bool))); + connect(unicodeButton, SIGNAL(toggled(bool)), divisionLabel, SLOT(setEnabled(bool))); + connect(unicodeButton, SIGNAL(toggled(bool)), divisionSlashButton, SLOT(setEnabled(bool))); + connect(unicodeButton, SIGNAL(toggled(bool)), divisionButton, SLOT(setEnabled(bool))); + connect(unicodeButton, SIGNAL(toggled(bool)), slashButton, SLOT(setEnabled(bool))); + +} + +QalculatePreferencesDialog::~QalculatePreferencesDialog() {} + +void QalculatePreferencesDialog::slotApply() { + rpn_keypad_only = rpnKeypadOnlyButton->isChecked(); + evalops.parse_options.dot_as_separator = dotAsSeparatorButton->isChecked(); + close_to_systray = systrayButton->isChecked(); + display_expression_status = statusButton->isChecked(); + switch(iconsButton->state()) { + case QButton::Off: { + use_icon_buttons = 0; + break; + } + case QButton::On: { + use_icon_buttons = 1; + break; + } + case QButton::NoChange: { + use_icon_buttons = -1; + break; + } + } + fetch_exchange_rates_at_startup = fetchExchangeRatesButton->isChecked(); + save_mode_on_exit = saveModeButton->isChecked(); + printops.use_unicode_signs = unicodeButton->isChecked(); + printops.lower_case_numbers = lowerCaseButton->isChecked(); + printops.lower_case_e = lowerCaseEButton->isChecked(); + if(alternativeBasePrefixButton->isChecked()) printops.base_display = BASE_DISPLAY_ALTERNATIVE; + else printops.base_display = BASE_DISPLAY_NORMAL; + printops.spell_out_logical_operators = spellOutLogicalOperatorsButton->isChecked(); + save_defs_on_exit = saveDefsButton->isChecked(); + use_custom_result_font = useCustomResultFontButton->isChecked(); + use_custom_expression_font = useCustomExpressionFontButton->isChecked(); + use_custom_status_font = useCustomStatusFontButton->isChecked(); + custom_result_font = resultFontEdit->font().toString(); + custom_expression_font = expressionFontEdit->font().toString(); + custom_status_font = statusFontEdit->font().toString(); + status_error_color = statusErrorColorButton->color(); + if(!status_error_color.isValid()) status_error_color.setNamedColor("red"); + status_warning_color = statusWarningColorButton->color(); + if(!status_warning_color.isValid()) status_warning_color.setNamedColor("blue"); + if(dotButton->isChecked()) { + printops.multiplication_sign = MULTIPLICATION_SIGN_DOT; + } else if(exButton->isChecked()) { + printops.multiplication_sign = MULTIPLICATION_SIGN_X; + } else { + printops.multiplication_sign = MULTIPLICATION_SIGN_ASTERISK; + } + if(divisionSlashButton->isChecked()) { + printops.division_sign = DIVISION_SIGN_DIVISION_SLASH; + } else if(divisionButton->isChecked()) { + printops.division_sign = DIVISION_SIGN_DIVISION; + } else { + printops.division_sign = DIVISION_SIGN_SLASH; + } + mainWin->applyPreferences(); +} +bool QalculatePreferencesDialog::editPreferences() { + + rpnKeypadOnlyButton->setChecked(rpn_keypad_only); + dotAsSeparatorButton->setChecked(evalops.parse_options.dot_as_separator); + systrayButton->setChecked(close_to_systray); + statusButton->setChecked(display_expression_status); + if(use_icon_buttons < 0) { + iconsButton->setNoChange(); + } else { + iconsButton->setChecked(use_icon_buttons > 0); + } + fetchExchangeRatesButton->setChecked(fetch_exchange_rates_at_startup); + saveModeButton->setChecked(save_mode_on_exit); + unicodeButton->setChecked(printops.use_unicode_signs); + lowerCaseButton->setChecked(printops.lower_case_numbers); + lowerCaseEButton->setChecked(printops.lower_case_e); + alternativeBasePrefixButton->setChecked(printops.base_display == BASE_DISPLAY_ALTERNATIVE); + spellOutLogicalOperatorsButton->setChecked(printops.spell_out_logical_operators); + saveDefsButton->setChecked(save_defs_on_exit); + useCustomResultFontButton->setChecked(use_custom_result_font); + useCustomExpressionFontButton->setChecked(use_custom_expression_font); + useCustomStatusFontButton->setChecked(use_custom_status_font); + QFont font1(resultWidget->font()); + font1.fromString(custom_result_font); + resultFontEdit->setFont(font1); + resultFontEdit->setEnabled(use_custom_result_font); + QFont font2(expressionWidget->font()); + font2.fromString(custom_expression_font); + expressionFontEdit->setFont(font2); + expressionFontEdit->setEnabled(use_custom_expression_font); + QFont font3(statusWidget_l->font()); + font3.fromString(custom_status_font); + statusFontEdit->setFont(font3); + statusFontEdit->setEnabled(use_custom_status_font); + statusErrorColorButton->setColor(status_error_color); + statusWarningColorButton->setColor(status_warning_color); + if(can_display_unicode_string_function(SIGN_MULTIDOT, (void*) dotButton)) dotButton->setText(SIGN_MULTIDOT); + else dotButton->setText(SIGN_SMALLCIRCLE); + switch(printops.multiplication_sign) { + case MULTIPLICATION_SIGN_DOT: { + dotButton->setChecked(true); + break; + } + case MULTIPLICATION_SIGN_X: { + exButton->setChecked(true); + break; + } + default: { + asteriskButton->setChecked(true); + break; + } + } + asteriskButton->setEnabled(printops.use_unicode_signs); + exButton->setEnabled(printops.use_unicode_signs); + dotButton->setEnabled(printops.use_unicode_signs); + multiplicationLabel->setEnabled(printops.use_unicode_signs); + switch(printops.division_sign) { + case DIVISION_SIGN_DIVISION_SLASH: { + divisionSlashButton->setChecked(true); + break; + } + case DIVISION_SIGN_DIVISION: { + divisionButton->setChecked(true); + break; + } + default: { + slashButton->setChecked(true); + break; + } + } + slashButton->setEnabled(printops.use_unicode_signs); + divisionSlashButton->setEnabled(printops.use_unicode_signs); + divisionButton->setEnabled(printops.use_unicode_signs); + divisionLabel->setEnabled(printops.use_unicode_signs); + + if(exec() == Accepted) { + slotApply(); + return true; + } + return false; + +} + + +#include "qalculatepreferencesdialog.moc" diff --git a/src/qalculatepreferencesdialog.h b/src/qalculatepreferencesdialog.h new file mode 100644 index 0000000..feb42d3 --- /dev/null +++ b/src/qalculatepreferencesdialog.h @@ -0,0 +1,57 @@ +/*************************************************************************** + * Copyright (C) 2005-2006 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEPREFERENCESDIALOG_H +#define QALCULATEPREFERENCESDIALOG_H + +#include + +class QCheckBox; +class QRadioButton; +class QLabel; +class KFontRequester; +class KColorButton; + +/** +@author Niklas Knutsson +*/ +class QalculatePreferencesDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculatePreferencesDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculatePreferencesDialog(); + + bool editPreferences(); + + QCheckBox *rpnKeypadOnlyButton, *systrayButton, *statusButton, *iconsButton, *fetchExchangeRatesButton, *saveModeButton, *saveDefsButton, *dotAsSeparatorButton, *unicodeButton, *lowerCaseButton, *lowerCaseEButton, *alternativeBasePrefixButton, *spellOutLogicalOperatorsButton, *useCustomResultFontButton, *useCustomExpressionFontButton, *useCustomStatusFontButton; + QRadioButton *dotButton, *exButton, *asteriskButton, *divisionSlashButton, *divisionButton, *slashButton; + QLabel *multiplicationLabel, *divisionLabel; + KFontRequester *resultFontEdit, *expressionFontEdit, *statusFontEdit; + KColorButton *statusErrorColorButton, *statusWarningColorButton; + +protected slots: + + void slotApply(); + +}; + +#endif diff --git a/src/qalculateresultdisplay.cpp b/src/qalculateresultdisplay.cpp new file mode 100644 index 0000000..91f5667 --- /dev/null +++ b/src/qalculateresultdisplay.cpp @@ -0,0 +1,495 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateresultdisplay.h" + +#include "qalculate_kde_utils.h" +#include "kqalculate.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern vector 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 += "
"; + const ExpressionName *ename = &f->preferredName(false, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) w); + str += ""; + str += ename->name.c_str(); + str += ""; + 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 += ""; + if(full_length) { + str += ""; + for(size_t i2 = 1; i2 <= f->countNames(); i2++) { + if(&f->getName(i2) != ename) { + str += "
"; + str += f->getName(i2).name.c_str(); + } + } + str += "
"; + if(f->subtype() == SUBTYPE_DATA_SET) { + str += "
"; + str += "
"; + 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("<", "<"); + str2.replace(">", ">"); + str += str2; + } + if(!f->description().empty()) { + str += "
"; + str += "
"; + QString str2 = f->description().c_str(); + str2.replace("<", "<"); + str2.replace(">", ">"); + 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("X", font()); + rt.setWidth(100); + QSimpleRichText rt2("X", font()); + rt2.setWidth(100); + int h2 = (int) (rt2.height() / 1.5); + h2 += h2 % 2; + int h = rt.height() * 2 + h2 + 2 * frameWidth(); + if(h < ms.height()) + h = ms.height(); + + return QSize(w, h); +} + +QSize QalculateResultDisplay::sizeHint() const { + return minimumSizeHint(); +} + + +#include "qalculateresultdisplay.moc" diff --git a/src/qalculateresultdisplay.h b/src/qalculateresultdisplay.h new file mode 100644 index 0000000..c5c2af1 --- /dev/null +++ b/src/qalculateresultdisplay.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATERESULTDISPLAY_H +#define QALCULATERESULTDISPLAY_H + +#include + +class QPopupMenu; +class QToolTip; +class MathStructure; + +/** +@author Niklas Knutsson +*/ +class QalculateResultDisplay : public QTextBrowser { + + Q_OBJECT + +public: + + QalculateResultDisplay(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateResultDisplay(); + + QPopupMenu *createPopupMenu(const QPoint & pos); + + QToolTip *tooltip; + const MathStructure *m_under_pointer; + QString name_under_pointer; + QPoint curpos; + + QSize minimumSizeHint() const; + QSize sizeHint() const; + + void setRightMargin(int); + +public slots: + + void onAnchorClicked(const QString&, const QString&); + void showParsedExpression(); + +private slots: + + void paletteChanged(); + void setSource(const QString &) {} + void showInfo(); + void editVector(); + void editMatrix(); + void onDoubleClicked(int, int); + void displayEngineering(); + void displayScientific(); + void displayNormal(); + +protected: + + void virtual_hook(int id, void* data); + void focusInEvent(QFocusEvent *fe); + void focusOutEvent(QFocusEvent *fe); + void keyPressEvent(QKeyEvent *e); + +}; + +#endif diff --git a/src/qalculatesetbasedialog.cpp b/src/qalculatesetbasedialog.cpp new file mode 100644 index 0000000..b95b205 --- /dev/null +++ b/src/qalculatesetbasedialog.cpp @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculatesetbasedialog.h" + +#include +#include +#include +#include +#include + +QalculateSetBaseDialog::QalculateSetBaseDialog(QWidget *parent, const char *name) + : KDialogBase(parent, name, false, i18n("Number Bases"), Close, Close) { + + QHBox *box = makeHBoxMainWidget(); + + radiogroup_output = new QVButtonGroup(i18n("Result Base"), box); + radiogroup_output->setRadioButtonExclusive(true); + new QRadioButton(i18n("Binary"), radiogroup_output); + new QRadioButton(i18n("Octal"), radiogroup_output); + new QRadioButton(i18n("Decimal"), radiogroup_output); + new QRadioButton(i18n("Hexadecimal"), radiogroup_output); + new QRadioButton(i18n("Other:"), radiogroup_output); + outputBaseBox = new QSpinBox(2, 36, 1, radiogroup_output); + outputBaseBox->setValue(10); + new QRadioButton(i18n("Sexagesimal"), radiogroup_output); + new QRadioButton(i18n("Time format"), radiogroup_output); + new QRadioButton(i18n("Roman numerals"), radiogroup_output); + + radiogroup_input = new QVButtonGroup(i18n("Expression Base"), box); + radiogroup_input->setRadioButtonExclusive(true); + new QRadioButton(i18n("Binary"), radiogroup_input); + new QRadioButton(i18n("Octal"), radiogroup_input); + new QRadioButton(i18n("Decimal"), radiogroup_input); + new QRadioButton(i18n("Hexadecimal"), radiogroup_input); + new QRadioButton(i18n("Other:"), radiogroup_input); + inputBaseBox = new QSpinBox(2, 36, 1, radiogroup_input); + inputBaseBox->setValue(10); + new QRadioButton(i18n("Roman numerals"), radiogroup_input); + +} + + +QalculateSetBaseDialog::~QalculateSetBaseDialog() {} + + +#include "qalculatesetbasedialog.moc" diff --git a/src/qalculatesetbasedialog.h b/src/qalculatesetbasedialog.h new file mode 100644 index 0000000..21955ba --- /dev/null +++ b/src/qalculatesetbasedialog.h @@ -0,0 +1,45 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATESETBASEDIALOG_H +#define QALCULATESETBASEDIALOG_H + +#include + +class QVButtonGroup; +class QSpinBox; + +/** +@author Niklas Knutsson +*/ +class QalculateSetBaseDialog : public KDialogBase { + + Q_OBJECT + +public: + + QalculateSetBaseDialog(QWidget *parent = 0, const char *name = 0); + virtual ~QalculateSetBaseDialog(); + + QVButtonGroup *radiogroup_input, *radiogroup_output; + QSpinBox *inputBaseBox, *outputBaseBox; + +}; + +#endif diff --git a/src/qalculateunitsdialog.cpp b/src/qalculateunitsdialog.cpp new file mode 100644 index 0000000..1918130 --- /dev/null +++ b/src/qalculateunitsdialog.cpp @@ -0,0 +1,560 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculateunitsdialog.h" +#include "qalculate_kde_utils.h" +#include "qalculateeditunitdialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern tree_struct unit_cats; +extern vector ia_units; +extern PrintOptions printops; +extern EvaluationOptions evalops; + +QalculateUnitsDialog::QalculateUnitsDialog(QWidget *parent, const char *name) : KDialog(parent, name, false) { + + unit_edit_dialog = NULL; + selected_category = ""; + selected_unit = NULL; + selected_to_unit = NULL; + block_unit_convert = true; + + QHBoxLayout *layout = new QHBoxLayout(this, marginHint(), spacingHint()); + + setCaption(i18n("Units")); + + QVBoxLayout *leftLayout = new QVBoxLayout(layout, spacingHint()); + + QSplitter *splitter = new QSplitter(Qt::Horizontal, this); + splitter->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + leftLayout->addWidget(splitter); + + categoryView = new KListView(splitter); + categoryView->addColumn(i18n("Category")); + categoryView->setRootIsDecorated(false); + + unitView = new KListView(splitter); + unitView->addColumn(i18n("Unit")); + unitView->addColumn(i18n("Names")); + unitView->addColumn(i18n("Base")); + unitView->setRootIsDecorated(false); + + convertGroup = new QGroupBox(3, Qt::Horizontal, i18n("Conversion"), this); + convertGroup->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); + convertGroup->setInsideSpacing(spacingHint()); + convertGroup->setInsideMargin(spacingHint()); + convertButton = new KPushButton(QIconSet(SmallIcon("reload")), "", convertGroup); + fromEdit = new KLineEdit("1", convertGroup); + fromEdit->setAlignment(Qt::AlignRight); + fromEdit->setMinimumWidth(100); + fromLabel = new QLabel(convertGroup); + equalsLabel = new QLabel("=", convertGroup); + equalsLabel->setAlignment(Qt::AlignRight); + toEdit = new KLineEdit("1", convertGroup); + toEdit->setAlignment(Qt::AlignRight); + toEdit->setMinimumWidth(100); + toCombo = new KComboBox(convertGroup); + leftLayout->addWidget(convertGroup); + + QVBoxLayout *buttonLayout = new QVBoxLayout(layout, spacingHint()); + + newButton = new QPushButton(i18n("New"), this); + buttonLayout->addWidget(newButton); + editButton = new QPushButton(i18n("Edit"), this); + editButton->setEnabled(false); + buttonLayout->addWidget(editButton); + deleteButton = new QPushButton(i18n("Delete"), this); + deleteButton->setEnabled(false); + buttonLayout->addWidget(deleteButton); + deactivateButton = new QPushButton(i18n("Deactivate"), this); + deactivateButton->setEnabled(false); + buttonLayout->addWidget(deactivateButton); + insertButton = new QPushButton(i18n("Insert"), this); + insertButton->setEnabled(false); + buttonLayout->addWidget(insertButton); + convertResultButton = new QPushButton(i18n("Convert Result"), this); + convertResultButton->setEnabled(false); + buttonLayout->addWidget(convertResultButton); + buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + helpButton = new KPushButton(KStdGuiItem::help(), this); + buttonLayout->addWidget(helpButton); + buttonClose = new KPushButton(KStdGuiItem::close(), this); + buttonLayout->addWidget(buttonClose); + + fromEdit->setFocus(); + + resize(QSize(675, 425).expandedTo(size())); + + connect(buttonClose, SIGNAL(clicked()), this, SLOT(close())); + connect(newButton, SIGNAL(clicked()), this, SLOT(newUnit())); + connect(editButton, SIGNAL(clicked()), this, SLOT(editUnit())); + connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteUnit())); + connect(deactivateButton, SIGNAL(clicked()), this, SLOT(deactivateUnit())); + connect(insertButton, SIGNAL(clicked()), this, SLOT(insertUnit())); + connect(convertResultButton, SIGNAL(clicked()), this, SLOT(convertResult())); + connect(unitView, SIGNAL(selectionChanged()), this, SLOT(unitSelected())); + connect(unitView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(unitDoubleClicked(QListViewItem*))); + connect(categoryView, SIGNAL(selectionChanged()), this, SLOT(categorySelected())); + connect(toCombo, SIGNAL(activated(int)), this, SLOT(toUnitSelected(int))); + connect(convertButton, SIGNAL(clicked()), this, SLOT(convertClicked())); + connect(fromEdit, SIGNAL(returnPressed()), this, SLOT(convert())); + connect(toEdit, SIGNAL(returnPressed()), this, SLOT(convertReversed())); + connect(fromEdit, SIGNAL(lostFocus()), this, SLOT(convert())); + connect(toEdit, SIGNAL(lostFocus()), this, SLOT(convertReversed())); + connect(helpButton, SIGNAL(clicked()), this, SLOT(slotHelp())); + +} + +QalculateUnitsDialog::~QalculateUnitsDialog() { +} + +void QalculateUnitsDialog::slotHelp() { + KApplication::kApplication()->invokeHelp("qalculate-managers"); +} + +void QalculateUnitsDialog::updateUnitTree() { + unitItems.clear(); + comboItems.clear(); + categoryItems.clear(); + categoryView->clear(); + QListViewItem *i = new KListViewItem(categoryView, i18n("All")), *i2; + categoryItems[i] = i18n("All"); + i->setOpen(true); + QString str; + tree_struct *item, *item2; + unit_cats.it = unit_cats.items.begin(); + if(unit_cats.it != unit_cats.items.end()) { + item = &*unit_cats.it; + ++unit_cats.it; + item->it = item->items.begin(); + } else { + item = NULL; + } + str = ""; + i2 = i; + while(item) { + str += "/"; + str += item->item.c_str(); + i = new KListViewItem(i2, item->item.c_str()); + i->setOpen(false); + categoryItems[i] = str; + if(str == selected_category) { + categoryView->ensureItemVisible(i); + categoryView->setSelected(i, true); + } + while(item && item->it == item->items.end()) { + int str_i = str.findRev("/"); + if(str_i < 0) { + str = ""; + } else { + str.truncate(str_i); + } + item = item->parent; + i = i->parent(); + i2 = i; + } + if(item) { + item2 = &*item->it; + if(item->it == item->items.begin()) + i2 = i; + ++item->it; + item = item2; + item->it = item->items.begin(); + } + } + if(!unit_cats.objects.empty()) { + //add "Uncategorized" category if there are units without category + i = new KListViewItem(categoryView, i18n("Uncategorized")); + categoryItems[i] = i18n("Uncategorized"); + if(selected_category == i18n("Uncategorized")) { + categoryView->ensureItemVisible(i); + categoryView->setSelected(i, true); + } + } + if(!ia_units.empty()) { + //add "Inactive" category if there are inactive units + i = new KListViewItem(categoryView, i18n("Inactive")); + categoryItems[i] = i18n("Inactive"); + if(selected_category == i18n("Inactive")) { + categoryView->ensureItemVisible(i); + categoryView->setSelected(i, true); + } + } + if(!categoryView->selectedItem()) { + //if no category has been selected (previously selected has been renamed/deleted), select "All" + selected_category = i18n("All"); + QListViewItemIterator it(categoryView); + if(it.current()) + categoryView->setSelected(it.current(), true); + } +} + +#define UPDATE_SELECTED_UNIT QListViewItem *i = unitView->selectedItem(); if(!i) return; selected_unit = unitItems[i]; if(!selected_unit) return; +#define CHECK_IF_UNIT_STILL_THERE if(!CALCULATOR->stillHasUnit(selected_unit)) {KMessageBox::error(this, i18n("Unit does not exist anymore.")); emit unitsChanged(); return;} + +void QalculateUnitsDialog::insertUnit() { + UPDATE_SELECTED_UNIT + CHECK_IF_UNIT_STILL_THERE + emit insertRequest(selected_unit); +} + +void QalculateUnitsDialog::convertResult() { + UPDATE_SELECTED_UNIT + CHECK_IF_UNIT_STILL_THERE + emit convertRequest(selected_unit); +} + +void QalculateUnitsDialog::deactivateUnit() { + UPDATE_SELECTED_UNIT + CHECK_IF_UNIT_STILL_THERE + selected_unit->setActive(!selected_unit->isActive()); + emit unitsChanged(); +} + +void QalculateUnitsDialog::deleteUnit() { + UPDATE_SELECTED_UNIT + CHECK_IF_UNIT_STILL_THERE + if(selected_unit->isLocal()) { + if(selected_unit->isUsedByOtherUnits()) { + //do not delete units that are used by other units + KMessageBox::error(this, i18n("Cannot delete unit as it is needed by other units.")); + return; + } + //ensure that all references are removed in Calculator + selected_unit->destroy(); + //update menus and trees + emit unitsChanged(); + } +} + + +void QalculateUnitsDialog::editUnit() { + UPDATE_SELECTED_UNIT + CHECK_IF_UNIT_STILL_THERE + if(!unit_edit_dialog) { + unit_edit_dialog = new QalculateEditUnitDialog(this); + } + Unit *u = unit_edit_dialog->editUnit(QString::null, selected_unit); + if(u) { + selected_unit = u; + if(!u->isActive()) { + selected_category = i18n("Inactive"); + } else if(u->category().empty()) { + selected_category = i18n("Uncategorized"); + } else { + selected_category = "/"; + selected_category += u->category().c_str(); + } + emit unitsChanged(); + } +} + +void QalculateUnitsDialog::newUnit() { + if(!unit_edit_dialog) { + unit_edit_dialog = new QalculateEditUnitDialog(this); + } + Unit *u = NULL; + if(selected_category.isEmpty() || selected_category[0] != '/') { + u = unit_edit_dialog->editUnit(); + } else { + QString str = selected_category; + str.remove(0, 1); + u = unit_edit_dialog->editUnit(str); + } + if(u) { + selected_unit = u; + if(!u->isActive()) { + selected_category = i18n("Inactive"); + } else if(u->category().empty()) { + selected_category = i18n("Uncategorized"); + } else { + selected_category = "/"; + selected_category += u->category().c_str(); + } + emit unitsChanged(); + } +} + +void QalculateUnitsDialog::unitDoubleClicked(QListViewItem*i) { + selected_unit = unitItems[i]; + if(!selected_unit) + return; + CHECK_IF_UNIT_STILL_THERE + if(!unit_edit_dialog) { + unit_edit_dialog = new QalculateEditUnitDialog(this); + } + Unit *u = unit_edit_dialog->editUnit(QString::null, selected_unit); + if(u) { + selected_unit = u; + if(!u->isActive()) { + selected_category = i18n("Inactive"); + } else if(u->category().empty()) { + selected_category = i18n("Uncategorized"); + } else { + selected_category = "/"; + selected_category += u->category().c_str(); + } + emit unitsChanged(); + } +} + + +void QalculateUnitsDialog::unitSelected() { + QListViewItem *selected = unitView->selectedItem(); + if(selected) { + Unit *u = unitItems[selected]; + if(!CALCULATOR->stillHasUnit(u)) { + KMessageBox::error(this, i18n("Unit does not exist anymore.")); + selected_unit = NULL; + emit unitsChanged(); + return; + } + //remember selection + selected_unit = u; + editButton->setEnabled(true); + insertButton->setEnabled(u->isActive()); + convertResultButton->setEnabled(true); + deleteButton->setEnabled(u->isLocal()); + deactivateButton->setEnabled(true); + convertGroup->setEnabled(true); + fromLabel->setText(u->print(true, printops.abbreviate_names, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) fromLabel).c_str()); + if(u->isActive()) + deactivateButton->setText(i18n("Deactivate")); + else + deactivateButton->setText(i18n("Activate")); + } else { + editButton->setEnabled(false); + insertButton->setEnabled(false); + deleteButton->setEnabled(false); + deactivateButton->setEnabled(false); + convertResultButton->setEnabled(false); + convertGroup->setEnabled(false); + selected_unit = NULL; + } + if(!block_unit_convert) convert(); +} + +void QalculateUnitsDialog::addUnitTreeItem(Unit *u) { + QString snames, sbase; + //display name, plural name and short name in the second column + AliasUnit *au; + for(size_t i = 1; i <= u->countNames(); i++) { + if(i > 1) snames += " / "; + snames += u->getName(i).name.c_str(); + } + //depending on unit type display relation to base unit(s) + switch(u->subtype()) { + case SUBTYPE_COMPOSITE_UNIT: { + snames = ""; + sbase = ((CompositeUnit*) u)->print(false, true, printops.use_unicode_signs, &can_display_unicode_string_function, (void*) unitView).c_str(); + break; + } + case SUBTYPE_ALIAS_UNIT: { + au = (AliasUnit*) u; + sbase = au->firstBaseUnit()->preferredDisplayName(printops.abbreviate_names, printops.use_unicode_signs, false, false, &can_display_unicode_string_function, (void*) unitView).name.c_str(); + if(au->firstBaseExponent() != 1) { + sbase += POWER; + sbase += QString::number(au->firstBaseExponent()); + } + break; + } + case SUBTYPE_BASE_UNIT: { + sbase = ""; + break; + } + } + QListViewItem *i = new KListViewItem(unitView, u->title(true).c_str(), snames, sbase); + unitItems[i] = u; + if(u == selected_unit) { + unitView->setSelected(i, true); + } +} + + +void QalculateUnitsDialog::categorySelected() { + block_unit_convert = true; + QListViewItem *selected = categoryView->selectedItem(); + bool no_cat = false, b_all = false, b_inactive = false; + unitView->clear(); + unitItems.clear(); + if(!selected) { + selected_category = ""; + unitSelected(); + return; + } + selected_category = categoryItems[selected]; + if(selected_category == i18n("All")) { + b_all = true; + } else if(selected_category == i18n("Uncategorized")) { + no_cat = true; + } else if(selected_category == i18n("Inactive")) { + b_inactive = true; + } + if(!b_all && !no_cat && !b_inactive && selected_category[0] == '/') { + string str = selected_category.ascii(); + str.erase(str.begin()); + for(size_t i = 0; i < CALCULATOR->units.size(); i++) { + if(CALCULATOR->units[i]->isActive() && CALCULATOR->units[i]->category().substr(0, selected_category.length() - 1) == str) { + addUnitTreeItem(CALCULATOR->units[i]); + } + } + } else { + string str = selected_category.ascii(); + for(size_t i = 0; i < CALCULATOR->units.size(); i++) { + if((b_inactive && !CALCULATOR->units[i]->isActive()) || (CALCULATOR->units[i]->isActive() && (b_all || (no_cat && CALCULATOR->units[i]->category().empty()) || (!b_inactive && CALCULATOR->units[i]->category() == str)))) { + addUnitTreeItem(CALCULATOR->units[i]); + } + } + } + if(!selected_unit || !unitView->selectedItem()) { + QListViewItemIterator it(unitView); + if(it.current()) + unitView->setSelected(it.current(), true); + } + //generate convert to menu + toCombo->blockSignals(true); + toCombo->clear(); + comboItems.clear(); + int i = 0, h = -1; + //add all units in units tree to menu + QListViewItemIterator it(unitView); + Unit *u; + while(it.current()) { + u = unitItems[it.current()]; + if(!selected_to_unit) { + selected_to_unit = u; + } + if(u) { + toCombo->insertItem(it.current()->text(0)); + comboItems.push_back(u); + if(selected_to_unit == u) + h = i; + } + i++; + ++it; + } + + //if no items were added to the menu, reset selected unit + if(i == 0) { + selected_to_unit = NULL; + } else { + //if no menu item was selected, select the first + if(h < 0) { + h = 0; + QListViewItemIterator it2(unitView); + if(it2.current()) { + selected_to_unit = unitItems[it2.current()]; + } else { + selected_to_unit = NULL; + } + } + toCombo->setCurrentItem(h); + } + toCombo->blockSignals(false); + block_unit_convert = false; + //update conversion display + convert(); +} + +void QalculateUnitsDialog::toUnitSelected(int index) { + if(index < (int) comboItems.size()) { + selected_to_unit = comboItems[index]; + convert(); + } +} +void QalculateUnitsDialog::convertClicked() { + if(toEdit->hasFocus()) { + convertReversed(); + } else { + convert(); + } +} +void QalculateUnitsDialog::convert() { + if(selected_unit && selected_to_unit) { + //determine conversion direction + bool b = false; + if(selected_unit == selected_to_unit) { + toEdit->setText(fromEdit->text()); + } else { + EvaluationOptions eo; + eo.approximation = APPROXIMATION_APPROXIMATE; + eo.parse_options.angle_unit = evalops.parse_options.angle_unit; + PrintOptions po; + po.is_approximate = &b; + po.number_fraction_format = FRACTION_DECIMAL; + MathStructure v_mstruct = CALCULATOR->convert(CALCULATOR->unlocalizeExpression(fromEdit->text().ascii(), evalops.parse_options), selected_unit, selected_to_unit, eo); + toEdit->setText(v_mstruct.print(po).c_str()); + b = b || v_mstruct.isApproximate(); + } + if(b && printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) equalsLabel)) { + equalsLabel->setText(SIGN_ALMOST_EQUAL); + } else { + equalsLabel->setText("="); + } + } +} +void QalculateUnitsDialog::convertReversed() { + if(selected_unit && selected_to_unit) { + bool b = false; + if(selected_unit == selected_to_unit) { + fromEdit->setText(toEdit->text()); + } else { + EvaluationOptions eo; + eo.approximation = APPROXIMATION_APPROXIMATE; + eo.parse_options.angle_unit = evalops.parse_options.angle_unit; + PrintOptions po; + po.is_approximate = &b; + po.number_fraction_format = FRACTION_DECIMAL; + MathStructure v_mstruct = CALCULATOR->convert(CALCULATOR->unlocalizeExpression(toEdit->text().ascii(), evalops.parse_options), selected_to_unit, selected_unit, eo); + fromEdit->setText(v_mstruct.print(po).c_str()); + b = b || v_mstruct.isApproximate(); + } + if(b && printops.use_unicode_signs && can_display_unicode_string_function(SIGN_ALMOST_EQUAL, (void*) equalsLabel)) { + equalsLabel->setText(SIGN_ALMOST_EQUAL); + } else { + equalsLabel->setText("="); + } + } +} + +void QalculateUnitsDialog::keyPressEvent(QKeyEvent *e) { + if(e->key() == Key_Return) { + convertClicked(); + e->accept(); + return; + } + KDialog::keyPressEvent(e); +} + + +#include "qalculateunitsdialog.moc" diff --git a/src/qalculateunitsdialog.h b/src/qalculateunitsdialog.h new file mode 100644 index 0000000..dfe9132 --- /dev/null +++ b/src/qalculateunitsdialog.h @@ -0,0 +1,108 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEUNITSDIALOG_H +#define QALCULATEUNITSDIALOG_H + +#include +#include +#include + +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 unitItems; + QMap categoryItems; + QValueVector comboItems; + + QGroupBox *convertGroup; + KListView *categoryView; + KListView *unitView; + QPushButton *newButton; + QPushButton *editButton; + QPushButton *deleteButton; + QPushButton *deactivateButton; + QPushButton *insertButton; + QPushButton *helpButton; + QPushButton *buttonClose; + QPushButton *convertResultButton; + QPushButton *convertButton; + QLabel *fromLabel, *equalsLabel; + KLineEdit *toEdit, *fromEdit; + KComboBox *toCombo; + + bool block_unit_convert; + +public slots: + + void updateUnitTree(); + void unitDoubleClicked(QListViewItem*); + void unitSelected(); + void categorySelected(); + void insertUnit(); + void deactivateUnit(); + void deleteUnit(); + void editUnit(); + void newUnit(); + void convertResult(); + void convertClicked(); + void convert(); + void convertReversed(); + void toUnitSelected(int); + +protected slots: + + void slotHelp(); + +signals: + + void unitsChanged(); + void insertRequest(Unit*); + void convertRequest(Unit*); + +protected: + + void keyPressEvent(QKeyEvent *e); + +}; + +#endif diff --git a/src/qalculatevariablesdialog.cpp b/src/qalculatevariablesdialog.cpp new file mode 100644 index 0000000..af6d024 --- /dev/null +++ b/src/qalculatevariablesdialog.cpp @@ -0,0 +1,493 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#include "qalculatevariablesdialog.h" +#include "qalculate_kde_utils.h" +#include "qalculateeditvariabledialog.h" +#include "qalculateeditmatrixvectordialog.h" +#include "qalculateeditunknownvariabledialog.h" +#include "qalculateexportcsvdialog.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern tree_struct variable_cats; +extern vector ia_variables; + +QalculateVariablesDialog::QalculateVariablesDialog(QWidget *parent, const char *name) : KDialog(parent, name, false) { + + export_csv_dialog = NULL; + variable_edit_dialog = NULL; + matrix_edit_dialog = NULL; + unknown_edit_dialog = NULL; + selected_category = ""; + selected_variable = NULL; + + QHBoxLayout *layout = new QHBoxLayout(this, marginHint(), spacingHint()); + + setCaption(i18n("Variables")); + + QSplitter *splitter = new QSplitter(Qt::Horizontal, this); + layout->addWidget(splitter); + + categoryView = new KListView(splitter); + categoryView->addColumn(i18n("Category")); + + variableView = new KListView(splitter); + variableView->addColumn(i18n("Variable Name")); + variableView->addColumn(i18n("Value")); + variableView->setRootIsDecorated(false); + + QVBoxLayout *buttonLayout = new QVBoxLayout(layout, spacingHint()); + + newButton = new QPushButton(i18n("New"), this); + buttonLayout->addWidget(newButton); + editButton = new QPushButton(i18n("Edit"), this); + editButton->setEnabled(false); + buttonLayout->addWidget(editButton); + deleteButton = new QPushButton(i18n("Delete"), this); + deleteButton->setEnabled(false); + buttonLayout->addWidget(deleteButton); + deactivateButton = new QPushButton(i18n("Deactivate"), this); + deactivateButton->setEnabled(false); + buttonLayout->addWidget(deactivateButton); + insertButton = new QPushButton(i18n("Insert"), this); + insertButton->setEnabled(false); + buttonLayout->addWidget(insertButton); + exportButton = new QPushButton(i18n("Export"), this); + exportButton->setEnabled(false); + buttonLayout->addWidget(exportButton); + buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)); + helpButton = new KPushButton(KStdGuiItem::help(), this); + buttonLayout->addWidget(helpButton); + buttonClose = new KPushButton(KStdGuiItem::close(), this); + buttonClose->setFocus(); + buttonLayout->addWidget(buttonClose); + + resize(QSize(675, 375).expandedTo(size())); + + connect(buttonClose, SIGNAL(clicked()), this, SLOT(close())); + connect(newButton, SIGNAL(clicked()), this, SLOT(newVariable())); + connect(editButton, SIGNAL(clicked()), this, SLOT(editVariable())); + connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteVariable())); + connect(deactivateButton, SIGNAL(clicked()), this, SLOT(deactivateVariable())); + connect(insertButton, SIGNAL(clicked()), this, SLOT(insertVariable())); + connect(exportButton, SIGNAL(clicked()), this, SLOT(exportVariable())); + connect(variableView, SIGNAL(selectionChanged()), this, SLOT(variableSelected())); + connect(variableView, SIGNAL(doubleClicked(QListViewItem*)), this, SLOT(variableDoubleClicked(QListViewItem*))); + connect(categoryView, SIGNAL(selectionChanged()), this, SLOT(categorySelected())); + connect(helpButton, SIGNAL(clicked()), this, SLOT(slotHelp())); + +} + +QalculateVariablesDialog::~QalculateVariablesDialog() {} + +void QalculateVariablesDialog::slotHelp() { + KApplication::kApplication()->invokeHelp("qalculate-managers"); +} + +void QalculateVariablesDialog::updateVariableTree() { + variableItems.clear(); + categoryItems.clear(); + categoryView->clear(); + QListViewItem *i = new KListViewItem(categoryView, i18n("All")), *i2; + categoryItems[i] = i18n("All"); + i->setOpen(true); + QString str; + tree_struct *item, *item2; + variable_cats.it = variable_cats.items.begin(); + if(variable_cats.it != variable_cats.items.end()) { + item = &*variable_cats.it; + ++variable_cats.it; + item->it = item->items.begin(); + } else { + item = NULL; + } + str = ""; + i2 = i; + while(item) { + str += "/"; + str += item->item.c_str(); + i = new KListViewItem(i2, item->item.c_str()); + i->setOpen(false); + categoryItems[i] = str; + if(str == selected_category) { + categoryView->ensureItemVisible(i); + categoryView->setSelected(i, true); + } + + while(item && item->it == item->items.end()) { + int str_i = str.findRev("/"); + if(str_i < 0) { + str = ""; + } else { + str.truncate(str_i); + } + item = item->parent; + i = i->parent(); + i2 = i; + } + if(item) { + item2 = &*item->it; + if(item->it == item->items.begin()) + i2 = i; + ++item->it; + item = item2; + item->it = item->items.begin(); + } + } + + if(!variable_cats.objects.empty()) { + //add "Uncategorized" category if there are variables without category + i = new KListViewItem(categoryView, i18n("Uncategorized")); + categoryItems[i] = i18n("Uncategorized"); + if(selected_category == i18n("Uncategorized")) { + categoryView->ensureItemVisible(i); + categoryView->setSelected(i, true); + } + } + if(!ia_variables.empty()) { + //add "Inactive" category if there are inactive variables + i = new KListViewItem(categoryView, i18n("Inactive")); + categoryItems[i] = i18n("Inactive"); + if(selected_category == i18n("Inactive")) { + categoryView->ensureItemVisible(i); + categoryView->setSelected(i, true); + } + } + if(!categoryView->selectedItem()) { + //if no category has been selected (previously selected has been renamed/deleted), select "All" + selected_category = i18n("All"); + QListViewItemIterator it(categoryView); + if(it.current()) + categoryView->setSelected(it.current(), true); + } +} + +#define UPDATE_SELECTED_VARIABLE QListViewItem *i = variableView->selectedItem(); if(!i) return; selected_variable = variableItems[i]; if(!selected_variable) return; +#define CHECK_IF_VARIABLE_STILL_THERE if(!CALCULATOR->stillHasVariable(selected_variable)) {KMessageBox::error(this, i18n("Variable does not exist anymore.")); emit variablesChanged(); return;} + +void QalculateVariablesDialog::exportVariable() { + UPDATE_SELECTED_VARIABLE + CHECK_IF_VARIABLE_STILL_THERE + if(selected_variable->isKnown()) { + if(!export_csv_dialog) { + export_csv_dialog = new QalculateExportCSVDialog(this); + } + export_csv_dialog->exportCSVFile((KnownVariable*) selected_variable); + } +} + + +void QalculateVariablesDialog::insertVariable() { + UPDATE_SELECTED_VARIABLE + CHECK_IF_VARIABLE_STILL_THERE + emit insertRequest(selected_variable); +} + + +void QalculateVariablesDialog::deactivateVariable() { + UPDATE_SELECTED_VARIABLE + CHECK_IF_VARIABLE_STILL_THERE + selected_variable->setActive(!selected_variable->isActive()); + emit variablesChanged(); +} + +void QalculateVariablesDialog::deleteVariable() { + UPDATE_SELECTED_VARIABLE + CHECK_IF_VARIABLE_STILL_THERE + if(selected_variable->isLocal()) { + //ensure that all references are removed in Calculator + selected_variable->destroy(); + //update menus and trees + emit variablesChanged(); + } +} + + +void QalculateVariablesDialog::editVariable() { + UPDATE_SELECTED_VARIABLE + CHECK_IF_VARIABLE_STILL_THERE + Variable *v = NULL; + if(selected_variable->isKnown()) { + if(((KnownVariable*) selected_variable)->get().isVector()) { + if(!matrix_edit_dialog) { + matrix_edit_dialog = new QalculateEditMatrixVectorDialog(this); + } + v = matrix_edit_dialog->editVariable(QString::null, (KnownVariable*) selected_variable); + } else { + if(!variable_edit_dialog) { + variable_edit_dialog = new QalculateEditVariableDialog(this); + } + v = variable_edit_dialog->editVariable(QString::null, (KnownVariable*) selected_variable); + } + } else { + if(!unknown_edit_dialog) { + unknown_edit_dialog = new QalculateEditUnknownVariableDialog(this); + } + v = unknown_edit_dialog->editVariable(QString::null, (UnknownVariable*) selected_variable); + } + if(v) { + selected_variable = v; + if(!v->isActive()) { + selected_category = i18n("Inactive"); + } else if(v->category().empty()) { + selected_category = i18n("Uncategorized"); + } else { + selected_category = "/"; + selected_category += v->category().c_str(); + } + emit variablesChanged(); + } +} + +void QalculateVariablesDialog::newVariable() { + if(!variable_edit_dialog) { + variable_edit_dialog = new QalculateEditVariableDialog(this); + } + Variable *v = NULL; + if(selected_category.isEmpty() || selected_category[0] != '/') { + v = variable_edit_dialog->editVariable(""); + } else { + QString str = selected_category; + str.remove(0, 1); + v = variable_edit_dialog->editVariable(str); + } + if(v) { + selected_variable = v; + if(!v->isActive()) { + selected_category = i18n("Inactive"); + } else if(v->category().empty()) { + selected_category = i18n("Uncategorized"); + } else { + selected_category = "/"; + selected_category += v->category().c_str(); + } + emit variablesChanged(); + } +} + +void QalculateVariablesDialog::variableDoubleClicked(QListViewItem*i) { + selected_variable = variableItems[i]; + if(!selected_variable) + return; + CHECK_IF_VARIABLE_STILL_THERE + Variable *v = NULL; + if(selected_variable->isKnown()) { + if(((KnownVariable*) selected_variable)->get().isVector()) { + if(!matrix_edit_dialog) { + matrix_edit_dialog = new QalculateEditMatrixVectorDialog(this); + } + v = matrix_edit_dialog->editVariable(QString::null, (KnownVariable*) selected_variable); + } else { + if(!variable_edit_dialog) { + variable_edit_dialog = new QalculateEditVariableDialog(this); + } + v = variable_edit_dialog->editVariable(QString::null, (KnownVariable*) selected_variable); + } + } else { + if(!unknown_edit_dialog) { + unknown_edit_dialog = new QalculateEditUnknownVariableDialog(this); + } + v = unknown_edit_dialog->editVariable(QString::null, (UnknownVariable*) selected_variable); + } + if(v) { + selected_variable = v; + if(!v->isActive()) { + selected_category = i18n("Inactive"); + } else if(v->category().empty()) { + selected_category = i18n("Uncategorized"); + } else { + selected_category = "/"; + selected_category += v->category().c_str(); + } + emit variablesChanged(); + } +} + + +void QalculateVariablesDialog::variableSelected() { + QListViewItem *selected = variableView->selectedItem(); + if(selected) { + Variable *v = variableItems[selected]; + if(!CALCULATOR->stillHasVariable(v)) { + KMessageBox::error(this, i18n("Variable does not exist anymore.")); + selected_variable = NULL; + emit variablesChanged(); + return; + } + //remember selection + selected_variable = v; + editButton->setEnabled(!is_answer_variable(v)); + insertButton->setEnabled(v->isActive()); + deleteButton->setEnabled(v->isLocal() && !is_answer_variable(v) && v != CALCULATOR->v_x && v != CALCULATOR->v_y && v != CALCULATOR->v_z); + deactivateButton->setEnabled(!is_answer_variable(v)); + if(v->isActive()) + deactivateButton->setText(i18n("Deactivate")); + else + deactivateButton->setText(i18n("Activate")); + exportButton->setEnabled(v->isKnown()); + } else { + editButton->setEnabled(false); + insertButton->setEnabled(false); + deleteButton->setEnabled(false); + deactivateButton->setEnabled(false); + exportButton->setEnabled(false); + selected_variable = NULL; + } +} + +void QalculateVariablesDialog::addVariableTreeItem(Variable *v) { + QString value; + if(is_answer_variable(v)) { + value = i18n("a previous result"); + } else if(v->isKnown()) { + if(((KnownVariable*) v)->isExpression()) { + value = CALCULATOR->localizeExpression(((KnownVariable*) v)->expression()).c_str(); + if(value.length() > 20) { + value.truncate(17); + value += "..."; + } + } else { + if(((KnownVariable*) v)->get().isMatrix()) { + value = i18n("matrix"); + } else if(((KnownVariable*) v)->get().isVector()) { + value = i18n("vector"); + } else { + value = CALCULATOR->printMathStructureTimeOut(((KnownVariable*) v)->get(), 30).c_str(); + } + } + } else { + if(((UnknownVariable*) v)->assumptions()) { + switch(((UnknownVariable*) v)->assumptions()->sign()) { + case ASSUMPTION_SIGN_POSITIVE: { + value = i18n("positive"); + break; + } + case ASSUMPTION_SIGN_NONPOSITIVE: { + value = i18n("non-positive"); + break; + } + case ASSUMPTION_SIGN_NEGATIVE: { + value = i18n("negative"); + break; + } + case ASSUMPTION_SIGN_NONNEGATIVE: { + value = i18n("non-negative"); + break; + } + case ASSUMPTION_SIGN_NONZERO: { + value = i18n("non-zero"); + break; + } + default: {} + } + if(!value.isEmpty() && !((UnknownVariable*) v)->assumptions()->type() == ASSUMPTION_TYPE_NONE) + value += " "; + switch(((UnknownVariable*) v)->assumptions()->type()) { + case ASSUMPTION_TYPE_INTEGER: { + value += i18n("integer"); + break; + } + case ASSUMPTION_TYPE_RATIONAL: { + value += i18n("rational"); + break; + } + case ASSUMPTION_TYPE_REAL: { + value += i18n("real"); + break; + } + case ASSUMPTION_TYPE_COMPLEX: { + value += i18n("complex"); + break; + } + case ASSUMPTION_TYPE_NUMBER: { + value += i18n("number"); + break; + } + case ASSUMPTION_TYPE_NONMATRIX: { + value += i18n("(not matrix)"); + break; + } + default: {} + } + if(value.isEmpty()) + value = i18n("unknown"); + } else { + value = i18n("default assumptions"); + } + } + QListViewItem *i = new KListViewItem(variableView, v->title(true).c_str(), value); + variableItems[i] = v; + if(v == selected_variable) { + variableView->setSelected(i, true); + } +} + + +void QalculateVariablesDialog::categorySelected() { + QListViewItem *selected = categoryView->selectedItem(); + bool no_cat = false, b_all = false, b_inactive = false; + variableView->clear(); + variableItems.clear(); + if(!selected) { + selected_category = ""; + variableSelected(); + return; + } + selected_category = categoryItems[selected]; + if(selected_category == i18n("All")) { + b_all = true; + } else if(selected_category == i18n("Uncategorized")) { + no_cat = true; + } else if(selected_category == i18n("Inactive")) { + b_inactive = true; + } + if(!b_all && !no_cat && !b_inactive && selected_category[0] == '/') { + string str = selected_category.ascii(); + str.erase(str.begin()); + for(size_t i = 0; i < CALCULATOR->variables.size(); i++) { + if(CALCULATOR->variables[i]->isActive() && CALCULATOR->variables[i]->category().substr(0, selected_category.length() - 1) == str) { + addVariableTreeItem(CALCULATOR->variables[i]); + } + } + } else { + string str = selected_category.ascii(); + for(size_t i = 0; i < CALCULATOR->variables.size(); i++) { + if((b_inactive && !CALCULATOR->variables[i]->isActive()) || (CALCULATOR->variables[i]->isActive() && (b_all || (no_cat && CALCULATOR->variables[i]->category().empty()) || (!b_inactive && CALCULATOR->variables[i]->category() == str)))) { + addVariableTreeItem(CALCULATOR->variables[i]); + } + } + } + if(!selected_variable || !variableView->selectedItem()) { + QListViewItemIterator it(variableView); + if(it.current()) + variableView->setSelected(it.current(), true); + } +} + + +#include "qalculatevariablesdialog.moc" diff --git a/src/qalculatevariablesdialog.h b/src/qalculatevariablesdialog.h new file mode 100644 index 0000000..2fa9bc5 --- /dev/null +++ b/src/qalculatevariablesdialog.h @@ -0,0 +1,92 @@ +/*************************************************************************** + * Copyright (C) 2005 by Niklas Knutsson * + * nq@altern.org * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef QALCULATEVARIABLESDIALOG_H +#define QALCULATEVARIABLESDIALOG_H + +#include +#include + +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 variableItems; + QMap 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

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 literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/plot-data.png b/doc/en/qalculate_kde/plot-data.png new file mode 100644 index 0000000000000000000000000000000000000000..cadd3ea24923892bf558e82f4e90df435c37b76f GIT binary patch literal 35356 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⁢)=^U&4A0AX`D9-CFKVG?l)Kr{99 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 Nr%(JrPCI7k^}sqKP3K?NPM^LW!Hm9 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 OfizXM!PSo~BmN8Iaftx{ literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/store-variable.png b/doc/en/qalculate_kde/store-variable.png new file mode 100644 index 0000000000000000000000000000000000000000..c5e7f1e4172f611b999768a90440ee74f7151207 GIT binary patch literal 16376 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 j(XEt?XCVF!GoA4M9X@UC3k@XLP#{K6q_ literal 0 HcmV?d00001 diff --git a/doc/en/qalculate_kde/unit-manager.png b/doc/en/qalculate_kde/unit-manager.png new file mode 100644 index 0000000000000000000000000000000000000000..6157405f1d863de512fec9c9b4d9c046ec78113d GIT binary patch literal 63199 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